/** * @class Loader * * @description * Responsibilities * > Being a facade for an ajax request of contents * * @method load(url) * @property {boolean} loading - state of the loader */ export default class Loader { /** * @param {*} onLoad( payload ) - called when the loading is complete * @param {*} onLoading - called when loading starts * @param {*} onError( error ) - called when the loading fails */ constructor( onLoad = null, onError = null, onLoading = null) { // state of the loader this.loading = false; this.onLoad = onLoad; this.onError = onError; this.onLoading = onLoading; // instantiate the Web Worker (parallel thread) this.loader = this._setWorker(); } /* * makes some adjustments to adapt the worker path * different dev environments */ _setLoaderWorker() { try{ if(window.Worker) return new Worker(this.worker); } catch(err) { console.log('_b| [loader] ',err.message); } } _loading() { // sets the status of loading this.loading = true; // launch the callback if(this.onLoading) this.onLoading(); } _error(error) { // resets the state this.loading = false; // launch the callback if(this.onError) this.onError(error); } _loaded( payload ) { // resets the state this.loading = false; // launch the callback if( this.onLoad ) this.onLoad( payload ); } /** * Execute loading. In a new thread, if possible. * takes as a parameter the url to load from and three callbacks * to update the state */ _parallelLoad(url) { if( this.loader ) { // dispatch of the incoming messages this.loader.onmessage = msg => { switch( msg.data.type ) { case 'loaded' : this._loaded.call( this, msg.data.payload ); break; case 'loading' : this._loading.call( this ); break; case 'error' : this._error.call( this, msg.data.payload ); break; } } // send the url to be loaded to the loader thread this.loader.postMessage({ url: url }); } else { console.log('_b| [loader] not threaded') // IE9 version not parallel at all var oReq = new XMLHttpRequest(); oReq.onload = response => { var payload = this.responseText; this._loaded.call( this, payload );} oReq.onerror = () => { load_self._error.call( this ); } oReq.open("GET", url); oReq.send(); this._loading.call( this ); } } /** * loads the content from the given url */ load( url ) { if (url != null) this._parallelLoad(url); } _setWorker() { var content = [ " onmessage = function(msg) { if(msg.data.url) load(msg.data.url); else postMessage({type : 'error', text : 'no url specified'}); }\n"+ " load = function(url) { var oReq = new XMLHttpRequest(); oReq.onload = transferComplete; oReq.onerror = transferFailed; console.log('_b| loading...', url); oReq.open('GET', url); oReq.send(); postMessage({type : 'loading'}); }\n"+ " function transferComplete() { console.log('_b| loaded'/*, this*/); postMessage({type: 'loaded', payload : this.response}); }\n"+ " function transferFailed() { console.log('_b| load error', this.responseText); postMessage({type: 'error', text : this.response}); }\n" ]; var blob = new Blob(content); return new Worker(window.URL.createObjectURL(blob)); } }