Commit 0e69426d authored by Aurélien Vermylen's avatar Aurélien Vermylen

Merge branch 'nodejs' of https://lab.nexedi.com/aurel/jio into clearroad

Conflicts:
	Gruntfile.js
	src/jio.storage/erp5storage.js
	src/jio.storage/mappingstorage.js
	test/jio.storage/mappingstorage.tests.js
	test/tests.html
parents 63be634c bf8de85a
......@@ -30,6 +30,7 @@ module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-connect');
grunt.loadNpmTasks('grunt-open');
grunt.loadNpmTasks('grunt-qunitnode');
// Project configuration.
grunt.initConfig({
......@@ -68,6 +69,26 @@ module.exports = function (grunt) {
nomen: true
}
},
jio_nodejs: {
src: ['src/jio-nodejs.js'],
directives: {
maxlen: 80,
indent: 2,
maxerr: 3,
node: true,
nomen: true
}
},
jio_nodejs_include: {
src: ['src/nodejs/include.js'],
directives: {
maxlen: 80,
indent: 2,
maxerr: 3,
node: true,
nomen: true
}
},
jio_storages: {
src: ['src/jio.storage/*.js'],
directives: {
......@@ -93,7 +114,7 @@ module.exports = function (grunt) {
predef: [
'jIO'
]
},
}
},
tests: {
src: ['test/**/*.js'],
......@@ -106,7 +127,7 @@ module.exports = function (grunt) {
'QUnit',
'jIO'
]
},
}
},
queries: {
src: ['src/queries/*.js'],
......@@ -136,8 +157,8 @@ module.exports = function (grunt) {
'QUnit',
'jIO'
]
},
},
}
}
},
concat: {
options: {
......@@ -187,6 +208,34 @@ module.exports = function (grunt) {
],
dest: 'dist/<%= pkg.name %>-<%= pkg.version %>.js'
// dest: 'jio.js'
},
nodejs: {
// duplicate files are ignored
src: [
// all the require for nodejs
'src/nodejs/include.js',
'src/nodejs/html5.js',
// queries
'src/queries/parser-begin.js',
'src/queries/build/parser.js',
'src/queries/parser-end.js',
'src/queries/query.js',
'src/jio.date/*.js',
'src/jio-nodejs.js',
'src/jio.storage/replicatestorage.js',
'src/jio.storage/uuidstorage.js',
'src/jio.storage/memorystorage.js',
'src/jio.storage/erp5storage.js',
'src/jio.storage/documentstorage.js',
'src/jio.storage/querystorage.js',
'src/jio.storage/localstorage.js',
'src/jio.storage/mappingstorage.js'
],
dest: 'dist/nodejs/jio.js'
}
},
uglify: {
......@@ -231,6 +280,22 @@ module.exports = function (grunt) {
// grunt doesn't like requirejs
files: ['test/tests.html']
},
// test jio with nodejs
qunitnode: {
all: [ "dist/nodejs/jio.js",
"test/jio.storage/memorystorage.tests.js",
"test/jio.storage/replicatestorage.tests.js",
"test/jio.storage/uuidstorage.tests.js",
"test/jio.storage/querystorage.tests.js",
"test/jio.storage/mappingstorage.tests.js",
"test/jio.storage/localstorage.tests.js",
"test/jio.storage/documentstorage.tests.js",
"test/jio.storage/erp5storage.tests.js"
],
options : {
force: true
}
},
watch: {
src: {
......@@ -245,7 +310,9 @@ module.exports = function (grunt) {
'<%= concat.jio.src %>',
'<%= qunit.files %>',
'test/**/*.js',
'examples/*'
'examples/*',
'src/jio-nodejs.js',
'src/nodejs/*.js'
],
tasks: ['default'],
options: {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -8,7 +8,7 @@
"Sven Franck <sven.franck@nexedi.com>"
],
"description": "Client-side JavaScript library to manage documents across multiple storages",
"main": "jio.js",
"main": "dist/nodejs/jio.js",
"directories": {
"example": "examples",
"test": "test"
......@@ -32,7 +32,17 @@
"rsvp": "git+https://lab.nexedi.com/nexedi/rsvp.js.git",
"uritemplate": "git+https://lab.nexedi.com/nexedi/uritemplate-js.git",
"moment": "2.13.0",
"rusha": "0.8.2"
"rusha": "0.8.2",
"urijs": "^1.18.9",
"xhr2": "^0.1.4",
"navigator": "^1.0.1",
"form-data": "^2.1.2",
"atob": "^2.0.3",
"node-localstorage": "^1.3.0",
"btoa": "^1.1.2",
"stream-buffers": "^3.0.1",
"mockdoc": "^0.0.2",
"sinon": "~2.1.0"
},
"devDependencies": {
"renderjs": "git+https://lab.nexedi.com/nexedi/renderjs.git",
......@@ -47,11 +57,12 @@
"grunt-contrib-watch": "~0.5.3",
"grunt-jslint": "~1.0.0",
"lz-string": "^1.4.4",
"sinon": "~1.7.3",
"sinon": "~2.1.0",
"jison": "~0.4.16",
"connect-livereload": "~0.3.0",
"grunt-open": "~0.2.2",
"grunt-contrib-connect": "~0.5.0"
"grunt-contrib-connect": "~0.5.0",
"grunt-qunitnode": "~1.0.0"
},
"engines": {
"npm": ">=1.3"
......
/*global window, RSVP, Blob, XMLHttpRequest, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator, FormData, StreamBuffers */
(function (window, RSVP, Blob, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator) {
"use strict";
if (window.openDatabase === undefined) {
window.openDatabase = function () {
throw new Error('WebSQL is not supported by ' + navigator.userAgent);
};
}
/* Safari does not define DOMError */
if (window.DOMError === undefined) {
window.DOMError = {};
}
var util = {},
jIO;
function jIOError(message, status_code) {
if ((message !== undefined) && (typeof message !== "string")) {
throw new TypeError('You must pass a string.');
}
this.message = message || "Default Message";
this.status_code = status_code || 500;
}
jIOError.prototype = new Error();
jIOError.prototype.constructor = jIOError;
util.jIOError = jIOError;
/**
* Send request with XHR and return a promise. xhr.onload: The promise is
* resolved when the status code is lower than 400 with the xhr object as
* first parameter. xhr.onerror: reject with xhr object as first
* parameter. xhr.onprogress: notifies the xhr object.
*
* @param {Object} param The parameters
* @param {String} [param.type="GET"] The request method
* @param {String} [param.dataType=""] The data type to retrieve
* @param {String} param.url The url
* @param {Any} [param.data] The data to send
* @param {Function} [param.beforeSend] A function called just before the
* send request. The first parameter of this function is the XHR object.
* @return {Promise} The promise
*/
function ajax(param) {
var xhr = new XMLHttpRequest();
return new RSVP.Promise(function (resolve, reject, notify) {
var k, buffer = new StreamBuffers.WritableStreamBuffer();
xhr.open(param.type || "GET", param.url, true);
xhr.responseType = param.dataType || "";
if (typeof param.headers === 'object' && param.headers !== null) {
for (k in param.headers) {
if (param.headers.hasOwnProperty(k)) {
xhr.setRequestHeader(k, param.headers[k]);
}
}
}
xhr.setRequestHeader("Accept", "*/*");
xhr.addEventListener("load", function (e) {
if (e.target.status >= 400) {
return reject(e);
}
resolve(e);
});
xhr.addEventListener("error", reject);
xhr.addEventListener("progress", notify);
if (typeof param.xhrFields === 'object' && param.xhrFields !== null) {
for (k in param.xhrFields) {
if (param.xhrFields.hasOwnProperty(k)) {
xhr[k] = param.xhrFields[k];
}
}
}
if (typeof param.beforeSend === 'function') {
param.beforeSend(xhr);
}
if (param.data instanceof FormData) {
xhr.setRequestHeader("Content-Type",
"multipart\/form-data; boundary=" + param.data.getBoundary());
param.data.pipe(buffer);
xhr.send(buffer.getContents());
} else {
xhr.send(param.data);
}
}, function () {
xhr.abort();
});
}
util.ajax = ajax;
function readBlobAsText(blob, encoding) {
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
fr.addEventListener("load", resolve);
fr.addEventListener("error", reject);
fr.addEventListener("progress", notify);
fr.readAsText(blob, encoding);
}, function () {
fr.abort();
});
}
util.readBlobAsText = readBlobAsText;
function readBlobAsArrayBuffer(blob) {
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
fr.addEventListener("load", resolve);
fr.addEventListener("error", reject);
fr.addEventListener("progress", notify);
fr.readAsArrayBuffer(blob);
}, function () {
fr.abort();
});
}
util.readBlobAsArrayBuffer = readBlobAsArrayBuffer;
function readBlobAsDataURL(blob) {
var fr = new FileReader();
return new RSVP.Promise(function (resolve, reject, notify) {
fr.addEventListener("load", resolve);
fr.addEventListener("error", reject);
fr.addEventListener("progress", notify);
fr.readAsDataURL(blob);
}, function () {
fr.abort();
});
}
util.readBlobAsDataURL = readBlobAsDataURL;
function stringify(obj) {
// Implement a stable JSON.stringify
// Object's keys are alphabetically ordered
var key,
key_list,
i,
value,
result_list;
if (obj === undefined) {
return undefined;
}
if (obj.constructor === Object) {
key_list = Object.keys(obj).sort();
result_list = [];
for (i = 0; i < key_list.length; i += 1) {
key = key_list[i];
value = stringify(obj[key]);
if (value !== undefined) {
result_list.push(stringify(key) + ':' + value);
}
}
return '{' + result_list.join(',') + '}';
}
if (obj.constructor === Array) {
result_list = [];
for (i = 0; i < obj.length; i += 1) {
result_list.push(stringify(obj[i]));
}
return '[' + result_list.join(',') + ']';
}
return JSON.stringify(obj);
}
util.stringify = stringify;
// https://gist.github.com/davoclavo/4424731
function dataURItoBlob(dataURI) {
if (dataURI === 'data:') {
return new Blob();
}
// convert base64 to raw binary data held in a string
var byteString = atob(dataURI.split(',')[1]),
// separate out the mime component
mimeString = dataURI.split(',')[0].split(':')[1],
// write the bytes of the string to an ArrayBuffer
arrayBuffer = new ArrayBuffer(byteString.length),
_ia = new Uint8Array(arrayBuffer),
i;
mimeString = mimeString.slice(0, mimeString.length - ";base64".length);
for (i = 0; i < byteString.length; i += 1) {
_ia[i] = byteString.charCodeAt(i);
}
return new Blob([arrayBuffer], {type: mimeString});
}
util.dataURItoBlob = dataURItoBlob;
// tools
function checkId(argument_list, storage, method_name) {
if (typeof argument_list[0] !== 'string' || argument_list[0] === '') {
throw new jIO.util.jIOError(
"Document id must be a non empty string on '" + storage.__type +
"." + method_name + "'.",
400
);
}
}
function checkAttachmentId(argument_list, storage, method_name) {
if (typeof argument_list[1] !== 'string' || argument_list[1] === '') {
throw new jIO.util.jIOError(
"Attachment id must be a non empty string on '" + storage.__type +
"." + method_name + "'.",
400
);
}
}
function declareMethod(klass, name, precondition_function, post_function) {
klass.prototype[name] = function () {
var argument_list = arguments,
context = this,
precondition_result;
return new RSVP.Queue()
.push(function () {
if (precondition_function !== undefined) {
return precondition_function.apply(
context.__storage,
[argument_list, context, name]
);
}
})
.push(function (result) {
var storage_method = context.__storage[name];
precondition_result = result;
if (storage_method === undefined) {
throw new jIO.util.jIOError(
"Capacity '" + name + "' is not implemented on '" +
context.__type + "'",
501
);
}
return storage_method.apply(
context.__storage,
argument_list
);
})
.push(function (result) {
if (post_function !== undefined) {
return post_function.call(
context,
argument_list,
result,
precondition_result
);
}
return result;
});
};
// Allow chain
return this;
}
/////////////////////////////////////////////////////////////////
// jIO Storage Proxy
/////////////////////////////////////////////////////////////////
function JioProxyStorage(type, storage) {
if (!(this instanceof JioProxyStorage)) {
return new JioProxyStorage();
}
this.__type = type;
this.__storage = storage;
}
declareMethod(JioProxyStorage, "put", checkId, function (argument_list) {
return argument_list[0];
});
declareMethod(JioProxyStorage, "get", checkId);
declareMethod(JioProxyStorage, "bulk");
declareMethod(JioProxyStorage, "remove", checkId, function (argument_list) {
return argument_list[0];
});
JioProxyStorage.prototype.post = function () {
var context = this,
argument_list = arguments;
return new RSVP.Queue()
.push(function () {
var storage_method = context.__storage.post;
if (storage_method === undefined) {
throw new jIO.util.jIOError(
"Capacity 'post' is not implemented on '" + context.__type + "'",
501
);
}
return context.__storage.post.apply(context.__storage, argument_list);
});
};
declareMethod(JioProxyStorage, 'putAttachment', function (argument_list,
storage,
method_name) {
checkId(argument_list, storage, method_name);
checkAttachmentId(argument_list, storage, method_name);
var options = argument_list[3] || {};
if (typeof argument_list[2] === 'string') {
argument_list[2] = new Blob([argument_list[2]], {
"type": options._content_type || options._mimetype ||
"text/plain;charset=utf-8"
});
} else if (!(argument_list[2] instanceof Blob)) {
throw new jIO.util.jIOError(
'Attachment content is not a blob',
400
);
}
});
declareMethod(JioProxyStorage, 'removeAttachment', function (argument_list,
storage,
method_name) {
checkId(argument_list, storage, method_name);
checkAttachmentId(argument_list, storage, method_name);
});
declareMethod(JioProxyStorage, 'getAttachment', function (argument_list,
storage,
method_name) {
var result = "blob";
// if (param.storage_spec.type !== "indexeddb" &&
// param.storage_spec.type !== "dav" &&
// (param.kwargs._start !== undefined
// || param.kwargs._end !== undefined)) {
// restCommandRejecter(param, [
// 'bad_request',
// 'unsupport',
// '_start, _end not support'
// ]);
// return false;
// }
checkId(argument_list, storage, method_name);
checkAttachmentId(argument_list, storage, method_name);
// Drop optional parameters, which are only used in postfunction
if (argument_list[2] !== undefined) {
result = argument_list[2].format || result;
delete argument_list[2].format;
}
return result;
}, function (argument_list, blob, convert) {
var result;
if (!(blob instanceof Blob)) {
throw new jIO.util.jIOError(
"'getAttachment' (" + argument_list[0] + " , " +
argument_list[1] + ") on '" + this.__type +
"' does not return a Blob.",
501
);
}
if (convert === "blob") {
result = blob;
} else if (convert === "data_url") {
result = new RSVP.Queue()
.push(function () {
return jIO.util.readBlobAsDataURL(blob);
})
.push(function (evt) {
return evt.target.result;
});
} else if (convert === "array_buffer") {
result = new RSVP.Queue()
.push(function () {
return jIO.util.readBlobAsArrayBuffer(blob);
})
.push(function (evt) {
return evt.target.result;
});
} else if (convert === "text") {
result = new RSVP.Queue()
.push(function () {
return jIO.util.readBlobAsText(blob);
})
.push(function (evt) {
return evt.target.result;
});
} else if (convert === "json") {
result = new RSVP.Queue()
.push(function () {
return jIO.util.readBlobAsText(blob);
})
.push(function (evt) {
return JSON.parse(evt.target.result);
});
} else {
throw new jIO.util.jIOError(
this.__type + ".getAttachment format: '" + convert +
"' is not supported",
400
);
}
return result;
});
JioProxyStorage.prototype.buildQuery = function () {
var storage_method = this.__storage.buildQuery,
context = this,
argument_list = arguments;
if (storage_method === undefined) {
throw new jIO.util.jIOError(
"Capacity 'buildQuery' is not implemented on '" + this.__type + "'",
501
);
}
return new RSVP.Queue()
.push(function () {
return storage_method.apply(
context.__storage,
argument_list
);
});
};
JioProxyStorage.prototype.hasCapacity = function (name) {
var storage_method = this.__storage.hasCapacity,
capacity_method = this.__storage[name];
if (capacity_method !== undefined) {
return true;
}
if ((storage_method === undefined) ||
!storage_method.apply(this.__storage, arguments)) {
throw new jIO.util.jIOError(
"Capacity '" + name + "' is not implemented on '" + this.__type + "'",
501
);
}
return true;
};
JioProxyStorage.prototype.allDocs = function (options) {
var context = this;
if (options === undefined) {
options = {};
}
return new RSVP.Queue()
.push(function () {
if (context.hasCapacity("list") &&
((options.query === undefined) || context.hasCapacity("query")) &&
((options.sort_on === undefined) || context.hasCapacity("sort")) &&
((options.select_list === undefined) ||
context.hasCapacity("select")) &&
((options.include_docs === undefined) ||
context.hasCapacity("include")) &&
((options.limit === undefined) || context.hasCapacity("limit"))) {
return context.buildQuery(options);
}
})
.push(function (result) {
return {
data: {
rows: result,
total_rows: result.length
}
};
});
};
declareMethod(JioProxyStorage, "allAttachments", checkId);
declareMethod(JioProxyStorage, "repair");
JioProxyStorage.prototype.repair = function () {
var context = this,
argument_list = arguments;
return new RSVP.Queue()
.push(function () {
var storage_method = context.__storage.repair;
if (storage_method !== undefined) {
return context.__storage.repair.apply(context.__storage,
argument_list);
}
});
};
/////////////////////////////////////////////////////////////////
// Storage builder
/////////////////////////////////////////////////////////////////
function JioBuilder() {
if (!(this instanceof JioBuilder)) {
return new JioBuilder();
}
this.__storage_types = {};
}
JioBuilder.prototype.createJIO = function (storage_spec, util) {
if (typeof storage_spec.type !== 'string') {
throw new TypeError("Invalid storage description");
}
if (!this.__storage_types[storage_spec.type]) {
throw new TypeError("Unknown storage '" + storage_spec.type + "'");
}
return new JioProxyStorage(
storage_spec.type,
new this.__storage_types[storage_spec.type](storage_spec, util)
);
};
JioBuilder.prototype.addStorage = function (type, Constructor) {
if (typeof type !== 'string') {
throw new TypeError(
"jIO.addStorage(): Argument 1 is not of type 'string'"
);
}
if (typeof Constructor !== 'function') {
throw new TypeError("jIO.addStorage(): " +
"Argument 2 is not of type 'function'");
}
if (this.__storage_types[type] !== undefined) {
throw new TypeError("jIO.addStorage(): Storage type already exists");
}
this.__storage_types[type] = Constructor;
};
JioBuilder.prototype.util = util;
JioBuilder.prototype.QueryFactory = QueryFactory;
JioBuilder.prototype.Query = Query;
/////////////////////////////////////////////////////////////////
// global
/////////////////////////////////////////////////////////////////
jIO = new JioBuilder();
window.jIO = jIO;
}(window, RSVP, Blob, QueryFactory, Query, atob,
FileReader, ArrayBuffer, Uint8Array, navigator));
......@@ -11,7 +11,7 @@
/*jslint nomen: true, unparam: true */
/*global jIO, UriTemplate, FormData, RSVP, URI, Blob,
SimpleQuery, ComplexQuery*/
SimpleQuery, ComplexQuery, btoa*/
(function (jIO, UriTemplate, FormData, RSVP, URI, Blob,
SimpleQuery, ComplexQuery) {
......@@ -24,8 +24,9 @@
"type": "GET",
"url": storage._url,
"xhrFields": {
withCredentials: true
}
withCredentials: storage._thisCredentials
},
"headers": storage._headers
});
})
.push(function (event) {
......@@ -50,8 +51,9 @@
view: options._view
}),
"xhrFields": {
withCredentials: true
}
withCredentials: storage._thisCredentials
},
"headers": storage._headers
});
})
.push(undefined, function (error) {
......@@ -128,8 +130,8 @@
});
}
function extractPropertyFromForm(context, id) {
return context.getAttachment(id, "view")
function extractPropertyFromForm(storage, id) {
return storage.getAttachment(id, "view")
.push(function (blob) {
return jIO.util.readBlobAsText(blob);
})
......@@ -149,20 +151,17 @@
}
this._url = spec.url;
this._default_view_reference = spec.default_view_reference;
this._headers = null;
this._thisCredentials = true;
if (spec.login !== undefined && spec.password !== undefined) {
this._headers = {"Authorization": "Basic "
+ btoa(spec.login + ":" + spec.password)};
this._thisCredentials = false;
}
}
function convertJSONToGet(json) {
var key,
result = json.data;
// Remove all ERP5 hateoas links / convert them into jIO ID
for (key in result) {
if (result.hasOwnProperty(key)) {
if (!result[key]) {
delete result[key];
}
}
}
return result;
return json.data;
}
ERP5Storage.prototype.get = function (id) {
......@@ -173,7 +172,7 @@
};
ERP5Storage.prototype.post = function (data) {
var context = this,
var storage = this,
new_id;
return getSiteDocument(this)
......@@ -186,15 +185,16 @@
url: site_hal._actions.add.href,
data: form_data,
xhrFields: {
withCredentials: true
}
withCredentials: storage._thisCredentials
},
"headers": storage._headers
});
})
.push(function (evt) {
var location = evt.target.getResponseHeader("X-Location"),
uri = new URI(location);
new_id = uri.segment(2);
return context.put(new_id, data);
return storage.put(new_id, data);
})
.push(function () {
return new_id;
......@@ -202,9 +202,9 @@
};
ERP5Storage.prototype.put = function (id, data) {
var context = this;
var storage = this;
return extractPropertyFromForm(context, id)
return extractPropertyFromForm(storage, id)
.push(function (result) {
var key,
json = result.form_data,
......@@ -237,7 +237,7 @@
403
);
}
return context.putAttachment(
return storage.putAttachment(
id,
result.action_href,
new Blob([JSON.stringify(form_data)], {type: "application/json"})
......@@ -246,10 +246,10 @@
};
ERP5Storage.prototype.allAttachments = function (id) {
var context = this;
var storage = this;
return getDocumentAndHateoas(this, id)
.push(function () {
if (context._default_view_reference === undefined) {
if (storage._default_view_reference === undefined) {
return {
links: {}
};
......@@ -262,6 +262,7 @@
};
ERP5Storage.prototype.getAttachment = function (id, action, options) {
var storage = this;
if (options === undefined) {
options = {};
}
......@@ -308,8 +309,9 @@
"dataType": "blob",
"url": action,
"xhrFields": {
withCredentials: true
}
withCredentials: storage._thisCredentials
},
"headers": storage._headers
};
if (options.start !== undefined || options.end !== undefined) {
start = options.start || 0;
......@@ -329,7 +331,11 @@
}
range = "bytes=" + start + "-" + end;
}
request_options.headers = {Range: range};
if (storage._headers === undefined) {
request_options.headers = {Range: range};
} else {
request_options.headers.Range = range;
}
}
return jIO.util.ajax(request_options);
})
......@@ -348,6 +354,7 @@
};
ERP5Storage.prototype.putAttachment = function (id, name, blob) {
var storage = this;
// Assert we use a callable on a document from the ERP5 site
if (name.indexOf(this._url) !== 0) {
throw new jIO.util.jIOError("Can not store outside ERP5: " +
......@@ -389,8 +396,9 @@
"data": data,
"dataType": "blob",
"xhrFields": {
withCredentials: true
}
withCredentials: storage._thisCredentials
},
"headers": storage._headers
});
});
};
......@@ -439,6 +447,7 @@
// jIO.Query.objectToSearchText(options.query) :
// undefined);
// }
var storage = this;
return getSiteDocument(this)
.push(function (site_hal) {
var query = options.query,
......@@ -507,8 +516,9 @@
local_roles: local_roles
}),
"xhrFields": {
withCredentials: true
}
withCredentials: storage._thisCredentials
},
"headers": storage._headers
});
})
.push(function (response) {
......
(function (env) {
"use strict";
var process = require("process");
env._html5_weakmap = new WeakMap();
function EventTarget() { env._html5_weakmap.set(this, Object.create(null)); }
EventTarget.prototype.addEventListener = function (type, listener) {
if (typeof listener !== "function") return;
var em = env._html5_weakmap.get(this);
type = "" + type;
if (em[type]) em[type].push(listener);
else em[type] = [listener];
};
EventTarget.prototype.removeEventListener = function (type, listener) {
if (typeof listener !== "function") return;
var em = env._html5_weakmap.get(this);
var i = 0, listeners = em[type];
type = "" + type;
if (listeners) for (; i < listeners.length; ++i) if (listeners[i] === listener) {
if (listeners.length === 1) { delete em[type]; return; }
listeners.splice(i, 1);
return;
}
};
EventTarget.prototype.dispatchEvent = function (event) {
var type = "" + event.type,
em = env._html5_weakmap.get(this),
ontype = "on" + type;
var i = 0, listeners;
if (typeof this[ontype] === "function") {
try { this[ontype](event); } catch (ignore) {}
}
if (listeners = em[type]) for (; i < listeners.length; ++i) {
try { listeners[i](event); } catch (ignore) {}
}
};
env.EventTarget = EventTarget;
function Blob(blobParts, options) {
// https://developer.mozilla.org/en-US/docs/Web/API/Blob
var i = 0; var priv = {}, buffers = [];
env._html5_weakmap.set(this, priv);
for (; i < blobParts.length; ++i) {
if (Buffer.isBuffer(blobParts[i])) {
buffers.push(blobParts[i]);
} else if (blobParts[i] instanceof Blob) {
buffers.push(env._html5_weakmap.get(blobParts[i]).data);
} else if (blobParts[i] instanceof ArrayBuffer) {
buffers.push(new Buffer(new Uint8Array(blobParts[i])));
} else {
buffers.push(new Buffer("" + blobParts[i]));
}
}
priv.data = Buffer.concat(buffers);
Object.defineProperty(this, "size", {enumerable: true, value: priv.data.length});
Object.defineProperty(this, "type", {enumerable: true, value: options ? "" + (options.type || "") : ""});
}
Blob.prototype.size = 0;
Blob.prototype.type = "";
Blob.prototype.slice = function (start, end, contentType) {
return new Blob([env._html5_weakmap.get(this).data.slice(start, end)], {type: contentType});
};
env.Blob = Blob;
function FileReader() { EventTarget.call(this); }
FileReader.prototype = Object.create(EventTarget.prototype);
Object.defineProperty(FileReader, "constructor", {value: FileReader});
FileReader.prototype.readAsText = function (blob) {
var priv = env._html5_weakmap.get(blob);
var text = priv.data.toString();
var event = Object.freeze({type: "load", target: this});
process.nextTick(() => {
this.result = text;
this.dispatchEvent(event);
});
};
FileReader.prototype.readAsArrayBuffer = function (blob) {
var priv = env._html5_weakmap.get(blob);
var arrayBuffer = new Uint8Array(priv.data).buffer;
var event = Object.freeze({type: "load", target: this});
process.nextTick(() => {
this.result = arrayBuffer;
this.dispatchEvent(event);
});
};
FileReader.prototype.readAsDataURL = function (blob) {
var priv = env._html5_weakmap.get(blob);
var dataUrl = "data:" + blob.type + ";base64," + priv.data.toString("base64");
var event = Object.freeze({type: "load", target: this});
process.nextTick(() => {
this.result = dataUrl;
this.dispatchEvent(event);
});
};
env.FileReader = FileReader;
}(global));
/*global global, require */
global.URI = require("urijs");
global.RSVP = require('rsvp');
global.UriTemplate = require("uritemplate");
global.moment = require('moment');
global.navigator = require('navigator');
global.Rusha = require('rusha');
global.FormData = require('form-data');
global.atob = require('atob');
var LocalStorage = require('node-localstorage').LocalStorage;
global.localStorage = new LocalStorage("jio");
global.btoa = require('btoa');
global.XMLHttpRequest = require('xhr2');
var Mockdoc = require("mockdoc");
global.document = new Mockdoc();
global.sinon = require('sinon');
global.StreamBuffers = require('stream-buffers');
global.window = global;
global.sessionStorage = {};
global.HTMLCanvasElement = {};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment