Skip to content
This repository was archived by the owner on Jul 13, 2020. It is now read-only.

Commit a08104a

Browse files
committedMay 5, 2015
new normalization spec algorithm
1 parent ed1a347 commit a08104a

8 files changed

+114
-174
lines changed
 

‎Gruntfile.js

+2
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ module.exports = function (grunt) {
2727
'src/dynamic-only.js',
2828
'src/url-polyfill.js',
2929
'src/system.js',
30+
'src/system-resolve.js',
3031
'src/wrapper-end.js'
3132
],
3233
'dist/<%= pkg.name %>-dev.src.js': [
@@ -37,6 +38,7 @@ module.exports = function (grunt) {
3738
'src/transpiler.js',
3839
'src/url-polyfill.js',
3940
'src/system.js',
41+
'src/system-resolve.js',
4042
'src/module-tag.js',
4143
'src/wrapper-end.js'
4244
]

‎src/system-resolve.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
var baseURLCache = {};
2+
3+
var absURLRegEx = /^([^\/]+:\/\/|\/)/;
4+
5+
// Normalization with module names as absolute URLs
6+
SystemLoader.prototype.normalize = function(name, parentName, parentAddress) {
7+
// ensure we have the baseURL URL object
8+
var baseURL = baseURLCache[this.baseURL] = baseURLCache[this.baseURL] || new URL(this.baseURL);
9+
10+
// not absolute or relative -> apply paths (what will be sites)
11+
if (!name.match(absURLRegEx) && name[0] != '.')
12+
name = new URL(applyPaths(this, name), baseURL).href;
13+
// apply parent-relative normalization, parentAddress is already normalized
14+
else
15+
name = new URL(name, parentAddress || baseURL).href;
16+
17+
// percent encode just '#' in module names
18+
// according to https://github.com/jorendorff/js-loaders/blob/master/browser-loader.js#L238
19+
// we should encode everything, but it breaks for servers that don't expect it
20+
// like in (https://github.com/systemjs/systemjs/issues/168)
21+
if (isBrowser)
22+
name = name.replace(/#/g, '%23');
23+
24+
return name;
25+
};
26+
27+
SystemLoader.prototype.locate = function(load) {
28+
return load.name;
29+
};

‎src/system.js

+38-89
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,44 @@ function SystemLoader(options) {
4545
this.paths = {};
4646
}
4747

48+
// NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
49+
function applyPaths(loader, name) {
50+
// most specific (most number of slashes in path) match wins
51+
var pathMatch = '', wildcard, maxSlashCount = 0;
52+
53+
// check to see if we have a paths entry
54+
for (var p in loader.paths) {
55+
var pathParts = p.split('*');
56+
if (pathParts.length > 2)
57+
throw new TypeError('Only one wildcard in a path is permitted');
58+
59+
// exact path match
60+
if (pathParts.length == 1) {
61+
if (name == p) {
62+
pathMatch = p;
63+
break;
64+
}
65+
}
66+
// wildcard path match
67+
else {
68+
var slashCount = p.split('/').length;
69+
if (slashCount >= maxSlashCount &&
70+
name.substr(0, pathParts[0].length) == pathParts[0] &&
71+
name.substr(name.length - pathParts[1].length) == pathParts[1]) {
72+
maxSlashCount = slashCount;
73+
pathMatch = p;
74+
wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
75+
}
76+
}
77+
}
78+
79+
var outPath = loader.paths[pathMatch] || name;
80+
if (wildcard)
81+
outPath = outPath.replace('*', wildcard);
82+
83+
return outPath;
84+
}
85+
4886
(function() {
4987
var fetchTextFromURL;
5088
if (typeof XMLHttpRequest != 'undefined') {
@@ -123,95 +161,6 @@ function SystemLoader(options) {
123161
LoaderProto.prototype = Loader.prototype;
124162
SystemLoader.prototype = new LoaderProto();
125163

126-
SystemLoader.prototype.normalize = function(name, parentName, parentAddress) {
127-
if (typeof name != 'string')
128-
throw new TypeError('Module name must be a string');
129-
130-
var segments = name.split('/');
131-
132-
// current segment
133-
var i = 0;
134-
// is the module name relative
135-
var rel = false;
136-
// number of backtracking segments
137-
var dotdots = 0;
138-
if (segments[0] == '.') {
139-
i++;
140-
rel = true;
141-
}
142-
else {
143-
while (segments[i] == '..') {
144-
i++;
145-
}
146-
if (i)
147-
rel = true;
148-
dotdots = i;
149-
}
150-
151-
if (!rel)
152-
return name;
153-
154-
// build the full module name
155-
var normalizedParts = [];
156-
var parentParts = (parentName || '').split('/');
157-
var normalizedLen = parentParts.length - 1 - dotdots;
158-
159-
normalizedParts = normalizedParts.concat(parentParts.splice(0, parentParts.length - 1 - dotdots));
160-
normalizedParts = normalizedParts.concat(segments.splice(i, segments.length - i));
161-
162-
return normalizedParts.join('/');
163-
};
164-
165-
var baseURLCache = {};
166-
167-
SystemLoader.prototype.locate = function(load) {
168-
var name = load.name;
169-
170-
// NB no specification provided for System.paths, used ideas discussed in https://github.com/jorendorff/js-loaders/issues/25
171-
172-
// most specific (most number of slashes in path) match wins
173-
var pathMatch = '', wildcard, maxSlashCount = 0;
174-
175-
// check to see if we have a paths entry
176-
for (var p in this.paths) {
177-
var pathParts = p.split('*');
178-
if (pathParts.length > 2)
179-
throw new TypeError('Only one wildcard in a path is permitted');
180-
181-
// exact path match
182-
if (pathParts.length == 1) {
183-
if (name == p) {
184-
pathMatch = p;
185-
break;
186-
}
187-
}
188-
// wildcard path match
189-
else {
190-
var slashCount = p.split('/').length;
191-
if (slashCount >= maxSlashCount &&
192-
name.substr(0, pathParts[0].length) == pathParts[0] &&
193-
name.substr(name.length - pathParts[1].length) == pathParts[1]) {
194-
maxSlashCount = slashCount;
195-
pathMatch = p;
196-
wildcard = name.substr(pathParts[0].length, name.length - pathParts[1].length - pathParts[0].length);
197-
}
198-
}
199-
}
200-
201-
var outPath = this.paths[pathMatch] || name;
202-
if (wildcard)
203-
outPath = outPath.replace('*', wildcard);
204-
205-
// percent encode just '#' in module names
206-
// according to https://github.com/jorendorff/js-loaders/blob/master/browser-loader.js#L238
207-
// we should encode everything, but it breaks for servers that don't expect it
208-
// like in (https://github.com/systemjs/systemjs/issues/168)
209-
if (isBrowser)
210-
outPath = outPath.replace(/#/g, '%23');
211-
212-
return new URL(outPath, baseURLCache[this.baseURL] = baseURLCache[this.baseURL] || new URL(this.baseURL)).href;
213-
};
214-
215164
SystemLoader.prototype.fetch = function(load) {
216165
return new Promise(function(resolve, reject) {
217166
fetchTextFromURL(load.address, resolve, reject);

‎src/transpiler.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ var transpile = (function() {
3939
return Promise.resolve(self.normalize(self.transpiler))
4040
.then(function(transpilerNormalized) {
4141
// load transpiler as a global (avoiding System clobbering)
42-
if (load.name === transpilerNormalized) {
42+
if (load.address === transpilerNormalized) {
4343
return {
4444
deps: [],
4545
execute: function() {
@@ -49,7 +49,7 @@ var transpile = (function() {
4949
__eval('(function(require,exports,module){' + load.source + '})();', load.address, __global);
5050
__global.System = curSystem;
5151
__global.Reflect.Loader = curLoader;
52-
return self.newModule({ 'default': __global[load.name], __useDefault: true });
52+
return self.newModule({ 'default': __global[self.transpiler], __useDefault: true });
5353
}
5454
};
5555
}

‎test/custom-loader.js

+6-6
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717

1818
var customLoader = new Reflect.Loader({
1919
normalize: function (name, parentName, parentAddress) {
20-
return new Promise(function (resolve, reject) {
20+
return new Promise(function(resolve, reject) {
2121
if (name == 'asdfasdf') {
2222
return setTimeout(function () {
2323
resolve('test/loader/async-norm.js');
@@ -39,9 +39,9 @@
3939
});
4040
}
4141

42-
if (load.name.substr(0, 5) == 'path/') {
43-
load.name = 'test/loader/' + load.name.substr(5);
44-
}
42+
if (load.name.match(/path\//))
43+
load.name = load.name.replace(/path\//, 'test/loader/');
44+
4545
return System.locate(load);
4646
},
4747
fetch: function (load) {
@@ -62,7 +62,7 @@
6262
return System.translate.apply(this, arguments);
6363
},
6464
instantiate: function (load) {
65-
if (load.name == this.transpiler) {
65+
if (load.name.match(/(traceur|babel.+\/browser).js$/)) {
6666
var transpiler = this.transpiler;
6767
return System.import(transpiler).then(function() {
6868
return {
@@ -96,7 +96,7 @@
9696
// normalize all dependencies now
9797
var normalizePromises = [];
9898
for (var i = 0; i < deps.length; i++) {
99-
normalizePromises.push(Promise.resolve(System.normalize(deps[i], load.name)));
99+
normalizePromises.push(Promise.resolve(System.normalize(deps[i], load.name, load.address)));
100100
}
101101

102102
return Promise.all(normalizePromises).then(function (resolvedDeps) {

‎test/custom-loader.spec.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -39,43 +39,44 @@ describe('Custom Loader', function () {
3939
function supposeToFail() {
4040
expect(false, 'should not be successful').to.be.ok();
4141
}
42+
var base = System.baseURL + 'test/loader/';
4243

4344
it('should make the normalize throw', function (done) {
4445
customLoader.import('test/loader/error1-parent.js')
4546
.then(supposeToFail, function (e) {
46-
expect(e).to.be.match(/Error loading "test\/loader\/error1-parent.js" at \S+error1-parent\.js/);
47+
expect(e).to.contain('Error loading "' + base + 'error1-parent.js" at ' + base + 'error1-parent\.js');
4748
})
4849
.then(done, done);
4950
});
5051

5152
it('should make the locate throw', function (done) {
5253
customLoader.import('test/loader/error2')
5354
.then(supposeToFail, function (e) {
54-
expect(e).to.be.match(/Error loading "test\/loader\/error2" at \S+test\/loader\/error2/);
55+
expect(e).to.be.contain('Error loading "' + base + 'error2" at ' + base + 'error2');
5556
})
5657
.then(done, done);
5758
});
5859

5960
it('should make the fetch throw', function (done) {
6061
customLoader.import('test/loader/error3')
6162
.then(supposeToFail, function (e) {
62-
expect(e).to.be.match(/Error loading "test\/loader\/error3" at \S+test\/loader\/error3/);
63+
expect(e).to.be.contain('Error loading "' + base + 'error3" at ' + base + 'error3');
6364
})
6465
.then(done, done);
6566
});
6667

6768
it('should make the translate throw', function (done) {
6869
customLoader.import('test/loader/error4')
6970
.then(supposeToFail, function (e) {
70-
expect(e).to.be.match(/Error loading "test\/loader\/error4" at \S+test\/loader\/error4/);
71+
expect(e).to.be.contain('Error loading "' + base + 'error4" at ' + base + 'error4');
7172
})
7273
.then(done, done);
7374
});
7475

7576
it('should make the instantiate throw', function (done) {
7677
customLoader.import('test/loader/error5')
7778
.then(supposeToFail, function (e) {
78-
expect(e).to.be.match(/Error loading "test\/loader\/error5" at \S+test\/loader\/error5/);
79+
expect(e).to.be.contain('Error loading "' + base + 'error5" at ' + base + 'error5');
7980
})
8081
.then(done, done);
8182
});

0 commit comments

Comments
 (0)