Swapped out XMLHttpRequest for a custom module
We made a module to encapsulate the logic that chooses the nodejs or browser dependency that actually downloads a file when the module is used.
This commit is contained in:
parent
5fcd313e2f
commit
9f33d8503e
21
gruntfile.js
21
gruntfile.js
|
@ -175,6 +175,21 @@ module.exports = function(grunt) {
|
||||||
remote: GIT_REMOTE,
|
remote: GIT_REMOTE,
|
||||||
branch: 'gh-pages',
|
branch: 'gh-pages',
|
||||||
force: true
|
force: true
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
connect: {
|
||||||
|
server_for_node: {
|
||||||
|
options: {
|
||||||
|
port: 1234,
|
||||||
|
base: '.'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
server_for_browser: {
|
||||||
|
options: {
|
||||||
|
port: 1234,
|
||||||
|
base: '.',
|
||||||
|
keepalive: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,6 +206,7 @@ module.exports = function(grunt) {
|
||||||
grunt.loadNpmTasks('grunt-git');
|
grunt.loadNpmTasks('grunt-git');
|
||||||
grunt.loadNpmTasks('grunt-prompt');
|
grunt.loadNpmTasks('grunt-prompt');
|
||||||
grunt.loadNpmTasks('grunt-shell');
|
grunt.loadNpmTasks('grunt-shell');
|
||||||
|
grunt.loadNpmTasks('grunt-contrib-connect');
|
||||||
|
|
||||||
grunt.registerTask('develop', ['clean', 'requirejs:develop']);
|
grunt.registerTask('develop', ['clean', 'requirejs:develop']);
|
||||||
grunt.registerTask('filer-test', ['clean', 'requirejs:test']);
|
grunt.registerTask('filer-test', ['clean', 'requirejs:test']);
|
||||||
|
@ -214,7 +230,6 @@ module.exports = function(grunt) {
|
||||||
' to ' + semver.inc(currentVersion, patchLevel).yellow + '?';
|
' to ' + semver.inc(currentVersion, patchLevel).yellow + '?';
|
||||||
grunt.config('prompt.confirm.options', promptOpts);
|
grunt.config('prompt.confirm.options', promptOpts);
|
||||||
|
|
||||||
// TODO: ADD NPM RELEASE
|
|
||||||
grunt.task.run([
|
grunt.task.run([
|
||||||
'prompt:confirm',
|
'prompt:confirm',
|
||||||
'checkBranch',
|
'checkBranch',
|
||||||
|
@ -226,7 +241,9 @@ module.exports = function(grunt) {
|
||||||
'npm-publish'
|
'npm-publish'
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
grunt.registerTask('test', ['check', 'filer-test', 'shell:mocha']);
|
grunt.registerTask('test-node', ['check', 'filer-test', 'connect:server_for_node', 'shell:mocha']);
|
||||||
|
grunt.registerTask('test-browser', ['check', 'filer-test', 'connect:server_for_browser']);
|
||||||
|
grunt.registerTask('test', ['test-node']);
|
||||||
|
|
||||||
grunt.registerTask('default', ['test']);
|
grunt.registerTask('default', ['test']);
|
||||||
};
|
};
|
||||||
|
|
11
package.json
11
package.json
|
@ -25,15 +25,17 @@
|
||||||
"url": "https://github.com/js-platform/filer.git"
|
"url": "https://github.com/js-platform/filer.git"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"bower": "~1.0.0"
|
"bower": "~1.0.0",
|
||||||
|
"request": "^2.36.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"chai": "~1.9.1",
|
||||||
"grunt": "~0.4.0",
|
"grunt": "~0.4.0",
|
||||||
"grunt-bump": "0.0.13",
|
"grunt-bump": "0.0.13",
|
||||||
"grunt-contrib-clean": "~0.4.0",
|
"grunt-contrib-clean": "~0.4.0",
|
||||||
"grunt-contrib-compress": "~0.4.1",
|
"grunt-contrib-compress": "~0.4.1",
|
||||||
"grunt-contrib-concat": "~0.1.3",
|
"grunt-contrib-concat": "~0.1.3",
|
||||||
"grunt-contrib-connect": "~0.7.1",
|
"grunt-contrib-connect": "^0.7.1",
|
||||||
"grunt-contrib-jshint": "~0.7.1",
|
"grunt-contrib-jshint": "~0.7.1",
|
||||||
"grunt-contrib-requirejs": "~0.4.0",
|
"grunt-contrib-requirejs": "~0.4.0",
|
||||||
"grunt-contrib-uglify": "~0.1.2",
|
"grunt-contrib-uglify": "~0.1.2",
|
||||||
|
@ -47,6 +49,7 @@
|
||||||
"semver": "^2.3.0",
|
"semver": "^2.3.0",
|
||||||
"requirejs": "~2.1.11",
|
"requirejs": "~2.1.11",
|
||||||
"mocha": "~1.18.2",
|
"mocha": "~1.18.2",
|
||||||
"chai": "~1.9.1"
|
"requirejs": "~2.1.11"
|
||||||
}
|
},
|
||||||
|
"main": "dist/filer_node.js"
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,82 @@
|
||||||
|
define(function(require) {
|
||||||
|
// Pull in node's request module if possible/needed
|
||||||
|
if (typeof XMLHttpRequest === 'undefined') {
|
||||||
|
// This is a stupid workaround for the fact that
|
||||||
|
// the r.js optimizer checks every require() call
|
||||||
|
// during optimization and throws an error if it
|
||||||
|
// can't find the module.
|
||||||
|
//
|
||||||
|
// This is only an issue with our browser build
|
||||||
|
// using `almond` (https://github.com/jrburke/almond)
|
||||||
|
// which doesn't fallback to node's require when we
|
||||||
|
// need it to.
|
||||||
|
var node_req = require;
|
||||||
|
var request = node_req('request');
|
||||||
|
}
|
||||||
|
|
||||||
|
function browserDownload(uri, callback) {
|
||||||
|
var query = new XMLHttpRequest();
|
||||||
|
query.onload = function() {
|
||||||
|
var err = query.status != 200 ? { message: query.statusText, code: query.status } : null,
|
||||||
|
data = err ? null : new Uint8Array(query.response);
|
||||||
|
|
||||||
|
callback(err, data);
|
||||||
|
};
|
||||||
|
query.open("GET", uri);
|
||||||
|
if("withCredentials" in query) {
|
||||||
|
query.withCredentials = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
query.responseType = "arraybuffer";
|
||||||
|
query.send();
|
||||||
|
}
|
||||||
|
|
||||||
|
function nodeDownload(uri, callback) {
|
||||||
|
request({
|
||||||
|
url: uri,
|
||||||
|
method: "GET",
|
||||||
|
encoding: null
|
||||||
|
}, function(err, msg, body) {
|
||||||
|
var data = null,
|
||||||
|
arrayBuffer,
|
||||||
|
statusCode,
|
||||||
|
arrayLength = body && body.length,
|
||||||
|
error;
|
||||||
|
|
||||||
|
msg = msg || null;
|
||||||
|
statusCode = msg && msg.statusCode;
|
||||||
|
|
||||||
|
error = statusCode != 200 ? { message: err || 'Not found!', code: statusCode } : null;
|
||||||
|
|
||||||
|
arrayBuffer = arrayLength && new ArrayBuffer(arrayLength);
|
||||||
|
|
||||||
|
// Convert buffer to Uint8Array
|
||||||
|
if (arrayBuffer && (statusCode == 200)) {
|
||||||
|
data = new Uint8Array(arrayBuffer);
|
||||||
|
for (var i = 0; i < body.length; ++i) {
|
||||||
|
data[i] = body[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(error, data);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
download: function(uri, callback) {
|
||||||
|
if (!uri) {
|
||||||
|
throw('Uri required!');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!callback) {
|
||||||
|
throw('Callback required');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof XMLHttpRequest === "undefined") {
|
||||||
|
nodeDownload(uri, callback);
|
||||||
|
} else {
|
||||||
|
browserDownload(uri, callback);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
|
@ -5,6 +5,7 @@ define(function(require) {
|
||||||
var Errors = require('src/errors');
|
var Errors = require('src/errors');
|
||||||
var Environment = require('src/shell/environment');
|
var Environment = require('src/shell/environment');
|
||||||
var async = require('async');
|
var async = require('async');
|
||||||
|
var Network = require('src/network');
|
||||||
|
|
||||||
require('zip');
|
require('zip');
|
||||||
require('unzip');
|
require('unzip');
|
||||||
|
@ -447,20 +448,18 @@ define(function(require) {
|
||||||
// Grab whatever is after the last / (assuming there is one) and
|
// Grab whatever is after the last / (assuming there is one) and
|
||||||
// remove any non-filename type chars(i.e., : and /). Like the real
|
// remove any non-filename type chars(i.e., : and /). Like the real
|
||||||
// wget, we leave query string or hash portions in tact.
|
// wget, we leave query string or hash portions in tact.
|
||||||
var path = options.filename || url.replace(/[:/]/g, '').split('/').pop();
|
var path = options.filename || url.replace(/[:/]/, '').split('/').pop();
|
||||||
path = Path.resolve(fs.cwd, path);
|
path = Path.resolve(fs.cwd, path);
|
||||||
|
|
||||||
function onerror() {
|
function onerror() {
|
||||||
callback(new Error('unable to get resource'));
|
callback(new Error('unable to get resource'));
|
||||||
}
|
}
|
||||||
|
|
||||||
var request = new XMLHttpRequest();
|
Network.download('get', url, function(err, data) {
|
||||||
request.onload = function() {
|
if (err || !data) {
|
||||||
if(request.status !== 200) {
|
|
||||||
return onerror();
|
return onerror();
|
||||||
}
|
}
|
||||||
|
|
||||||
var data = new Uint8Array(request.response);
|
|
||||||
fs.writeFile(path, data, function(err) {
|
fs.writeFile(path, data, function(err) {
|
||||||
if(err) {
|
if(err) {
|
||||||
callback(err);
|
callback(err);
|
||||||
|
@ -468,15 +467,7 @@ define(function(require) {
|
||||||
callback(null, path);
|
callback(null, path);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
|
||||||
request.onerror = onerror;
|
|
||||||
request.open("GET", url, true);
|
|
||||||
if("withCredentials" in request) {
|
|
||||||
request.withCredentials = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
request.responseType = "arraybuffer";
|
|
||||||
request.send();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Shell.prototype.unzip = function(zipfile, options, callback) {
|
Shell.prototype.unzip = function(zipfile, options, callback) {
|
||||||
|
|
|
@ -7,7 +7,8 @@
|
||||||
//
|
//
|
||||||
// ?filer-dist/filer.js --> use dist/filer.js
|
// ?filer-dist/filer.js --> use dist/filer.js
|
||||||
// ?filer-dist/filer.min.js --> use dist/filer.min.js
|
// ?filer-dist/filer.min.js --> use dist/filer.min.js
|
||||||
// ?<default> --> (default) use src/filer.js with require
|
// ?filer-src/filer.js --> use src/filer.js with require
|
||||||
|
// ?<default> --> (default) use dist/filer-test.js with require
|
||||||
var filerArgs = window.filerArgs = {};
|
var filerArgs = window.filerArgs = {};
|
||||||
var config = (function() {
|
var config = (function() {
|
||||||
var query = window.location.search.substring(1);
|
var query = window.location.search.substring(1);
|
||||||
|
@ -51,24 +52,39 @@ var config = (function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support src/ filer via require
|
// Support src/ filer via require
|
||||||
|
if(filerArgs['filer-src/filer.js']) {
|
||||||
|
return {
|
||||||
|
paths: {
|
||||||
|
"tests": "../tests",
|
||||||
|
"src": "../src",
|
||||||
|
"spec": "../tests/spec",
|
||||||
|
"bugs": "../tests/bugs",
|
||||||
|
"util": "../tests/lib/test-utils",
|
||||||
|
"Filer": "../src/index"
|
||||||
|
},
|
||||||
|
baseUrl: "../lib",
|
||||||
|
optimize: "none",
|
||||||
|
shim: {
|
||||||
|
// TextEncoder and TextDecoder shims. encoding-indexes must get loaded first,
|
||||||
|
// and we use a fake one for reduced size, since we only care about utf8.
|
||||||
|
"encoding": {
|
||||||
|
deps: ["encoding-indexes-shim"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Support dist/filer-test.js
|
||||||
return {
|
return {
|
||||||
paths: {
|
paths: {
|
||||||
"tests": "../tests",
|
"tests": "../tests",
|
||||||
"src": "../src",
|
|
||||||
"spec": "../tests/spec",
|
"spec": "../tests/spec",
|
||||||
"bugs": "../tests/bugs",
|
"bugs": "../tests/bugs",
|
||||||
"util": "../tests/lib/test-utils",
|
"util": "../tests/lib/test-utils",
|
||||||
"Filer": "../src/index"
|
"Filer": "../dist/filer-test"
|
||||||
},
|
},
|
||||||
baseUrl: "../lib",
|
baseUrl: "../lib",
|
||||||
optimize: "none",
|
optimize: "none"
|
||||||
shim: {
|
|
||||||
// TextEncoder and TextDecoder shims. encoding-indexes must get loaded first,
|
|
||||||
// and we use a fake one for reduced size, since we only care about utf8.
|
|
||||||
"encoding": {
|
|
||||||
deps: ["encoding-indexes-shim"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
define(['../../src/network'], function(network) {
|
||||||
|
|
||||||
|
describe('Network download tool', function() {
|
||||||
|
if(typeof XMLHttpRequest === "undefined") {
|
||||||
|
it('should connect to server',function(done) {
|
||||||
|
var request = require('request');
|
||||||
|
request({
|
||||||
|
url: 'http://localhost:8080/package.json',
|
||||||
|
method: 'GET',
|
||||||
|
encoding: 'utf-8'
|
||||||
|
}, function(error, msg, body) {
|
||||||
|
expect(error).not.to.exist;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
it('should throw an exception when a URI is not passed', function(done) {
|
||||||
|
expect(function() {
|
||||||
|
network.download(undefined, function(error, data, statusCode) {});
|
||||||
|
}).to.throwError;
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should get an error when a non-existent path is specified', function(done) {
|
||||||
|
network.download('http://localhost:8080/file-non-existent', function(error, data, statusCode) {
|
||||||
|
expect(error).not.to.exist;
|
||||||
|
expect(statusCode).to.eql('404');
|
||||||
|
expect(data).to.be.a(null);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should download a resource from the server', function(done) {
|
||||||
|
network.download('http://localhost:8080/package.json', function(error, data, statusCode) {
|
||||||
|
expect(error).not.to.exist;
|
||||||
|
expect(statusCode).to.eql('200');
|
||||||
|
expect(data).to.exist;
|
||||||
|
expect(data).to.have.length.above(0);
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -38,6 +38,7 @@ define([
|
||||||
"spec/time-flags.spec",
|
"spec/time-flags.spec",
|
||||||
"spec/fs.watch.spec",
|
"spec/fs.watch.spec",
|
||||||
"spec/errors.spec",
|
"spec/errors.spec",
|
||||||
|
"spec/lib.spec",
|
||||||
|
|
||||||
// Filer.FileSystem.providers.*
|
// Filer.FileSystem.providers.*
|
||||||
"spec/providers/providers.spec",
|
"spec/providers/providers.spec",
|
||||||
|
|
Loading…
Reference in New Issue