diff --git a/lib/loader.js b/lib/loader.js
index e53abf1..e530280 100644
--- a/lib/loader.js
+++ b/lib/loader.js
@@ -137,129 +137,6 @@ function logloads(loads) {
return -1;
};
- // --- ---
- // parse function is used to parse a load record
- // tree traversal, NB should use visitor pattern here
- function traverse(object, iterator, parent, parentProperty) {
- var key, child;
- if (iterator(object, parent, parentProperty) === false)
- return;
- for (key in object) {
- if (!object.hasOwnProperty(key))
- continue;
- if (key == 'location' || key == 'type')
- continue;
- child = object[key];
- if (typeof child == 'object' && child !== null)
- traverse(child, iterator, object, key);
- }
- }
- // given a syntax tree, return the import list
- function getImports(moduleTree) {
- var imports = [];
-
- function addImport(name) {
- if (indexOf.call(imports, name) == -1)
- imports.push(name);
- }
-
- traverse(moduleTree, function(node) {
- // import {} from 'foo';
- // export * from 'foo';
- // export { ... } from 'foo';
- // module x from 'foo';
- if (node.type == 'EXPORT_DECLARATION') {
- if (node.declaration.moduleSpecifier)
- addImport(node.declaration.moduleSpecifier.token.processedValue);
- }
- else if (node.type == 'IMPORT_DECLARATION')
- addImport(node.moduleSpecifier.token.processedValue);
- else if (node.type == 'MODULE_DECLARATION')
- addImport(node.expression.token.processedValue);
- });
- return imports;
- }
- // Returns an array of ModuleSpecifiers
- function parse(load) {
- if (!traceur) {
- if (typeof window == 'undefined')
- traceur = require('traceur');
- else if (__global.traceur)
- traceur = __global.traceur;
- else
- throw new TypeError('Include Traceur for module syntax support');
- }
-
- console.assert(load.source, 'Non-empty source');
-
- var depsList, curRegister, curSystem, oldSourceMaps, oldModules;
- (function () {
- try {
- var parser = new traceur.syntax.Parser(new traceur.syntax.SourceFile(load.address, load.source));
- var body = parser.parseModule();
-
- load.kind = 'declarative';
- depsList = getImports(body);
-
- oldSourceMaps = traceur.options.sourceMaps;
- oldModules = traceur.options.modules;
-
- traceur.options.sourceMaps = true;
- traceur.options.modules = 'instantiate';
-
- var reporter = new traceur.util.ErrorReporter();
-
- reporter.reportMessageInternal = function(location, kind, format, args) {
- throw new SyntaxError(kind, location.start && location.start.line_, location.start && location.start.column_);
- }
-
- // traceur expects its version of System
- curSystem = __global.System;
- __global.System = __global.traceurSystem;
-
- var tree = (new traceur.codegeneration.module.AttachModuleNameTransformer(load.name)).transformAny(body);
- tree = (new traceur.codegeneration.FromOptionsTransformer(reporter)).transform(tree);
-
- var sourceMapGenerator = new traceur.outputgeneration.SourceMapGenerator({ file: load.address });
- var options = { sourceMapGenerator: sourceMapGenerator };
-
- var source = traceur.outputgeneration.TreeWriter.write(tree, options);
-
- if (__global.btoa)
- source += '\n//# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(options.sourceMap))) + '\n';
-
- // now run System.register
- curRegister = System.register;
-
- System.register = function(name, deps, declare) {
- // store the registered declaration as load.declare
- load.declare = typeof name == 'string' ? declare : deps;
- }
-
- __eval(source, __global, load.name);
- }
- catch(e) {
- if (e.name == 'SyntaxError' || e.name == 'TypeError')
- e.message = 'Evaluating ' + (load.name || load.address) + '\n\t' + e.message;
- if (curRegister)
- System.register = curRegister;
- if (curSystem)
- __global.System = curSystem;
- if (oldSourceMaps)
- traceur.options.sourceMaps = oldSourceMaps;
- if (oldModules)
- traceur.options.modules = oldModules;
- throw e;
- }
- }());
- System.register = curRegister;
- __global.System = curSystem;
- traceur.options.sourceMaps = oldSourceMaps;
- traceur.options.modules = oldModules;
- return depsList;
- }
- // --- ---
-
// 15.2.3 - Runtime Semantics: Loader State
// 15.2.3.11
@@ -390,7 +267,8 @@ function logloads(loads) {
var depsList;
if (instantiateResult === undefined) {
load.address = load.address || 'anon' + ++anonCnt;
- depsList = parse(load);
+ load.kind = 'declarative';
+ depsList = loader.loaderObj.parse(load);
}
else if (typeof instantiateResult == 'object') {
depsList = instantiateResult.deps || [];
@@ -1033,7 +911,7 @@ function logloads(loads) {
return loader.modules[name].module;
}
- return importPromises[name] || createImportPromise(name,
+ return importPromises[name] || createImportPromise(name,
loadModule(loader, name, options || {})
.then(function(load) {
delete importPromises[name];
@@ -1117,6 +995,9 @@ function logloads(loads) {
translate: function(load) {
return load.source;
},
+ parse: function(load) {
+ throw new TypeError('Loader.parse is not implemented');
+ },
// 26.3.3.18.5
instantiate: function(load) {
}
@@ -1134,8 +1015,4 @@ function logloads(loads) {
})();
- function __eval(__source, __global, __moduleName) {
- eval('var __moduleName = "' + (__moduleName || '').replace('"', '\"') + '"; (function() { ' + __source + ' \n }).call(__global);');
- }
-
})(typeof global !== 'undefined' ? global : this);
diff --git a/lib/system.js b/lib/system.js
index 86ee247..2b8b8a7 100644
--- a/lib/system.js
+++ b/lib/system.js
@@ -11,255 +11,398 @@
*/
(function (global) {
- var isBrowser = typeof window != 'undefined';
- var Loader = global.Reflect && global.Reflect.Loader || require('./loader');
- var Promise = global.Promise || require('es6-promise').Promise;
-
- // Helpers
- // Absolute URL parsing, from https://gist.github.com/Yaffle/1088850
- function parseURI(url) {
- var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
- // authority = '//' + user + ':' + pass '@' + hostname + ':' port
- return (m ? {
- href : m[0] || '',
- protocol : m[1] || '',
- authority: m[2] || '',
- host : m[3] || '',
- hostname : m[4] || '',
- port : m[5] || '',
- pathname : m[6] || '',
- search : m[7] || '',
- hash : m[8] || ''
- } : null);
- }
- function removeDotSegments(input) {
- var output = [];
- input.replace(/^(\.\.?(\/|$))+/, '')
- .replace(/\/(\.(\/|$))+/g, '/')
- .replace(/\/\.\.$/, '/../')
- .replace(/\/?[^\/]*/g, function (p) {
- if (p === '/..')
- output.pop();
- else
- output.push(p);
- });
- return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
- }
- function toAbsoluteURL(base, href) {
- href = parseURI(href || '');
- base = parseURI(base || '');
+ (function() {
+
+ var isBrowser = typeof window != 'undefined';
+ var Loader = global.Reflect && global.Reflect.Loader || require('./loader');
+ var Promise = global.Promise || require('es6-promise').Promise;
+
+ // Helpers
+ // Absolute URL parsing, from https://gist.github.com/Yaffle/1088850
+ function parseURI(url) {
+ var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
+ // authority = '//' + user + ':' + pass '@' + hostname + ':' port
+ return (m ? {
+ href : m[0] || '',
+ protocol : m[1] || '',
+ authority: m[2] || '',
+ host : m[3] || '',
+ hostname : m[4] || '',
+ port : m[5] || '',
+ pathname : m[6] || '',
+ search : m[7] || '',
+ hash : m[8] || ''
+ } : null);
+ }
+ function removeDotSegments(input) {
+ var output = [];
+ input.replace(/^(\.\.?(\/|$))+/, '')
+ .replace(/\/(\.(\/|$))+/g, '/')
+ .replace(/\/\.\.$/, '/../')
+ .replace(/\/?[^\/]*/g, function (p) {
+ if (p === '/..')
+ output.pop();
+ else
+ output.push(p);
+ });
+ return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
+ }
+ function toAbsoluteURL(base, href) {
+
+ href = parseURI(href || '');
+ base = parseURI(base || '');
- return !href || !base ? null : (href.protocol || base.protocol) +
- (href.protocol || href.authority ? href.authority : base.authority) +
- removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
- (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
- href.hash;
- }
+ return !href || !base ? null : (href.protocol || base.protocol) +
+ (href.protocol || href.authority ? href.authority : base.authority) +
+ removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
+ (href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
+ href.hash;
+ }
- var fetchTextFromURL;
- if (isBrowser) {
- fetchTextFromURL = function(url, fulfill, reject) {
- var xhr = new XMLHttpRequest();
- var sameDomain = true;
- if (!('withCredentials' in xhr)) {
- // check if same domain
- var domainCheck = /^(\w+:)?\/\/([^\/]+)/.exec(url);
- if (domainCheck) {
- sameDomain = domainCheck[2] === window.location.host;
- if (domainCheck[1])
- sameDomain &= domainCheck[1] === window.location.protocol;
+ var fetchTextFromURL;
+ if (isBrowser) {
+ fetchTextFromURL = function(url, fulfill, reject) {
+ var xhr = new XMLHttpRequest();
+ var sameDomain = true;
+ if (!('withCredentials' in xhr)) {
+ // check if same domain
+ var domainCheck = /^(\w+:)?\/\/([^\/]+)/.exec(url);
+ if (domainCheck) {
+ sameDomain = domainCheck[2] === window.location.host;
+ if (domainCheck[1])
+ sameDomain &= domainCheck[1] === window.location.protocol;
+ }
+ }
+ if (!sameDomain) {
+ xhr = new XDomainRequest();
+ xhr.onload = load;
+ xhr.onerror = error;
+ xhr.ontimeout = error;
+ }
+ function load() {
+ fulfill(xhr.responseText);
}
+ function error() {
+ reject(xhr.statusText + ': ' + url || 'XHR error');
+ }
+
+ xhr.onreadystatechange = function () {
+ if (xhr.readyState === 4) {
+ if (xhr.status === 200 || (xhr.status == 0 && xhr.responseText)) {
+ load();
+ } else {
+ error();
+ }
+ }
+ };
+ xhr.open("GET", url, true);
+ xhr.send(null);
+ }
+ }
+ else {
+ var fs;
+ fetchTextFromURL = function(url, fulfill, reject) {
+ fs = fs || require('fs');
+ return fs.readFile(url, function(err, data) {
+ if (err)
+ return reject(err);
+ else
+ fulfill(data + '');
+ });
}
- if (!sameDomain) {
- xhr = new XDomainRequest();
- xhr.onload = load;
- xhr.onerror = error;
- xhr.ontimeout = error;
+ }
+
+ // IE8 support
+ var indexOf = Array.prototype.indexOf || function(item) {
+ for (var i = 0, thisLen = this.length; i < thisLen; i++) {
+ if (this[i] === item) {
+ return i;
+ }
}
- function load() {
- fulfill(xhr.responseText);
+ return -1;
+ };
+
+ // given a syntax tree, return the import list
+ function getImports(moduleTree) {
+ var imports = [];
+
+ function addImport(name) {
+ if (indexOf.call(imports, name) == -1)
+ imports.push(name);
}
- function error() {
- reject(xhr.statusText + ': ' + url || 'XHR error');
+
+ // tree traversal, NB should use visitor pattern here
+ function traverse(object, iterator, parent, parentProperty) {
+ var key, child;
+ if (iterator(object, parent, parentProperty) === false)
+ return;
+ for (key in object) {
+ if (!object.hasOwnProperty(key))
+ continue;
+ if (key == 'location' || key == 'type')
+ continue;
+ child = object[key];
+ if (typeof child == 'object' && child !== null)
+ traverse(child, iterator, object, key);
+ }
}
- xhr.onreadystatechange = function () {
- if (xhr.readyState === 4) {
- if (xhr.status === 200 || (xhr.status == 0 && xhr.responseText)) {
- load();
- } else {
- error();
- }
+ traverse(moduleTree, function(node) {
+ // import {} from 'foo';
+ // export * from 'foo';
+ // export { ... } from 'foo';
+ // module x from 'foo';
+ if (node.type == 'EXPORT_DECLARATION') {
+ if (node.declaration.moduleSpecifier)
+ addImport(node.declaration.moduleSpecifier.token.processedValue);
}
- };
- xhr.open("GET", url, true);
- xhr.send(null);
- }
- }
- else {
- var fs;
- fetchTextFromURL = function(url, fulfill, reject) {
- fs = fs || require('fs');
- return fs.readFile(url, function(err, data) {
- if (err)
- return reject(err);
- else
- fulfill(data + '');
+ else if (node.type == 'IMPORT_DECLARATION')
+ addImport(node.moduleSpecifier.token.processedValue);
+ else if (node.type == 'MODULE_DECLARATION')
+ addImport(node.expression.token.processedValue);
});
+ return imports;
}
- }
- var System = new Loader({
- global: isBrowser ? window : global,
- strict: true,
- normalize: function(name, parentName, parentAddress) {
- if (typeof name != 'string')
- throw new TypeError('Module name must be a string');
-
- var segments = name.split('/');
-
- if (segments.length == 0)
- throw new TypeError('No module name provided');
-
- // current segment
- var i = 0;
- // is the module name relative
- var rel = false;
- // number of backtracking segments
- var dotdots = 0;
- if (segments[0] == '.') {
- i++;
- if (i == segments.length)
- throw new TypeError('Illegal module name "' + name + '"');
- rel = true;
- }
- else {
- while (segments[i] == '..') {
+ var System = new Loader({
+ global: isBrowser ? window : global,
+ strict: true,
+ normalize: function(name, parentName, parentAddress) {
+ if (typeof name != 'string')
+ throw new TypeError('Module name must be a string');
+
+ var segments = name.split('/');
+
+ if (segments.length == 0)
+ throw new TypeError('No module name provided');
+
+ // current segment
+ var i = 0;
+ // is the module name relative
+ var rel = false;
+ // number of backtracking segments
+ var dotdots = 0;
+ if (segments[0] == '.') {
i++;
if (i == segments.length)
throw new TypeError('Illegal module name "' + name + '"');
- }
- if (i)
rel = true;
- dotdots = i;
- }
+ }
+ else {
+ while (segments[i] == '..') {
+ i++;
+ if (i == segments.length)
+ throw new TypeError('Illegal module name "' + name + '"');
+ }
+ if (i)
+ rel = true;
+ dotdots = i;
+ }
- for (var j = i; j < segments.length; j++) {
- var segment = segments[j];
- if (segment == '' || segment == '.' || segment == '..')
- throw new TypeError('Illegal module name "' + name + '"');
- }
+ for (var j = i; j < segments.length; j++) {
+ var segment = segments[j];
+ if (segment == '' || segment == '.' || segment == '..')
+ throw new TypeError('Illegal module name "' + name + '"');
+ }
- if (!rel)
- return name;
+ if (!rel)
+ return name;
- // build the full module name
- var normalizedParts = [];
- var parentParts = (parentName || '').split('/');
- var normalizedLen = parentParts.length - 1 - dotdots;
+ // build the full module name
+ var normalizedParts = [];
+ var parentParts = (parentName || '').split('/');
+ var normalizedLen = parentParts.length - 1 - dotdots;
- normalizedParts = normalizedParts.concat(parentParts.splice(0, parentParts.length - 1 - dotdots));
- normalizedParts = normalizedParts.concat(segments.splice(i, segments.length - i));
+ normalizedParts = normalizedParts.concat(parentParts.splice(0, parentParts.length - 1 - dotdots));
+ normalizedParts = normalizedParts.concat(segments.splice(i, segments.length - i));
- return normalizedParts.join('/');
- },
- locate: function(load) {
- var name = load.name;
+ return normalizedParts.join('/');
+ },
+ locate: function(load) {
+ var name = load.name;
- // NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
+ // NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
- // most specific (longest) match wins
- var pathMatch = '', wildcard;
+ // most specific (longest) match wins
+ var pathMatch = '', wildcard;
- // check to see if we have a paths entry
- for (var p in this.paths) {
- var pathParts = p.split('*');
- if (pathParts.length > 2)
- throw new TypeError('Only one wildcard in a path is permitted');
+ // check to see if we have a paths entry
+ for (var p in this.paths) {
+ var pathParts = p.split('*');
+ if (pathParts.length > 2)
+ throw new TypeError('Only one wildcard in a path is permitted');
- // exact path match
- if (pathParts.length == 1) {
- if (name == p && p.length > pathMatch.length)
- pathMatch = p;
- }
+ // exact path match
+ if (pathParts.length == 1) {
+ if (name == p && p.length > pathMatch.length)
+ pathMatch = p;
+ }
- // wildcard path match
- else {
- if (name.substr(0, pathParts[0].length) == pathParts[0] && name.substr(name.length - pathParts[1].length) == pathParts[1]) {
- pathMatch = p;
- wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
+ // wildcard path match
+ else {
+ if (name.substr(0, pathParts[0].length) == pathParts[0] && name.substr(name.length - pathParts[1].length) == pathParts[1]) {
+ pathMatch = p;
+ wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
+ }
}
}
+
+ var outPath = this.paths[pathMatch];
+ if (wildcard)
+ outPath = outPath.replace('*', wildcard);
+
+ return toAbsoluteURL(this.baseURL, outPath);
+ },
+ fetch: function(load) {
+ return new Promise(function(resolve, reject) {
+ fetchTextFromURL(toAbsoluteURL(this.baseURL, load.address), function(source) {
+ resolve(source);
+ }, reject);
+ });
+ },
+ });
+ // --- ---
+
+ // parse function is used to parse a load record
+ // Returns an array of ModuleSpecifiers
+ System.parse = function(load) {
+ if (!traceur) {
+ if (typeof window == 'undefined')
+ traceur = require('traceur');
+ else if (global.traceur)
+ traceur = global.traceur;
+ else
+ throw new TypeError('Include Traceur for module syntax support');
}
- var outPath = this.paths[pathMatch];
- if (wildcard)
- outPath = outPath.replace('*', wildcard);
-
- return toAbsoluteURL(this.baseURL, outPath);
- },
- fetch: function(load) {
- return new Promise(function(resolve, reject) {
- fetchTextFromURL(toAbsoluteURL(this.baseURL, load.address), function(source) {
- resolve(source);
- }, reject);
- });
+ console.assert(load.source, 'Non-empty source');
+
+ var depsList, curSystem, oldSourceMaps, oldModules;
+ (function () {
+ try {
+
+ var parser = new traceur.syntax.Parser(new traceur.syntax.SourceFile(load.address, load.source));
+ var body = parser.parseModule();
+
+ load.kind = 'declarative';
+ depsList = getImports(body);
+
+ oldSourceMaps = traceur.options.sourceMaps;
+ oldModules = traceur.options.modules;
+
+ traceur.options.sourceMaps = true;
+ traceur.options.modules = 'instantiate';
+
+ var reporter = new traceur.util.ErrorReporter();
+
+ reporter.reportMessageInternal = function(location, kind, format, args) {
+ throw new SyntaxError(kind, location.start && location.start.line_, location.start && location.start.column_);
+ }
+
+ // traceur expects its version of System
+ curSystem = global.System;
+ global.System = global.traceurSystem;
+
+ var tree = (new traceur.codegeneration.module.AttachModuleNameTransformer(load.name)).transformAny(body);
+ tree = (new traceur.codegeneration.FromOptionsTransformer(reporter)).transform(tree);
+
+ var sourceMapGenerator = new traceur.outputgeneration.SourceMapGenerator({ file: load.address });
+ var options = { sourceMapGenerator: sourceMapGenerator };
+
+ var source = traceur.outputgeneration.TreeWriter.write(tree, options);
+
+ if (global.btoa)
+ source += '\n//# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(options.sourceMap))) + '\n';
+
+ __eval(source, global, load);
+ }
+ catch(e) {
+ if (e.name == 'SyntaxError' || e.name == 'TypeError')
+ e.message = 'Evaluating ' + (load.name || load.address) + '\n\t' + e.message;
+ if (curSystem)
+ global.System = curSystem;
+ if (oldSourceMaps)
+ traceur.options.sourceMaps = oldSourceMaps;
+ if (oldModules)
+ traceur.options.modules = oldModules;
+ throw e;
+ }
+ }());
+ global.System = curSystem;
+ traceur.options.sourceMaps = oldSourceMaps;
+ traceur.options.modules = oldModules;
+ return depsList;
}
- });
- if (isBrowser) {
- var href = window.location.href.split('#')[0].split('?')[0];
- System.baseURL = href.substring(0, href.lastIndexOf('/') + 1);
- }
- else {
- System.baseURL = './';
- }
- System.paths = { '*': '*.js' };
-
- //