playem.js
function Loader () {
  var FINAL_STATES = {'loaded': true, 'complete': true, 4: true}
  var head = document.getElementsByTagName('head')[0]
  var pending = {}
  var counter = 0
  return {
    /**
     * @private
     * @callback dataCallback
     * @memberof Loader.prototype
     * @param {object|string} data JSON object, or string returned by request as `responseText`.
     */
    /**
     * Loads and returns a JSON resource asynchronously, using XMLHttpRequest (AJAX).
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JSON resource to load.
     * @param {dataCallback} cb Callback function with request's data as first parameter.
     */
    loadJSON: function (src, cb) {
      // if (pending[src]) return cb && cb();
      // pending[src] = true;
      // cross-domain ajax call
      var xdr = new window.XMLHttpRequest()
      xdr.onload = function () {
        var data = xdr.responseText
        try {
          data = JSON.parse(data)
        } catch (e) {};
        cb(data)
        // delete pending[src];
      }
      xdr.open('GET', src, true)
      xdr.send()
    },
    /**
     * @private
     * @callback errorCallback
     * @memberof Loader.prototype
     * @param {Error} error Error caught thru the `error` event or `appendChild()` call, if any.
     */
    /**
     * Loads a JavaScript resource into the page.
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JavaScript resource to load into the page.
     * @param {errorCallback} cb Callback function with error as first parameter, if any.
     */
    includeJS: function (src, cb) {
      var inc, nt
      if (pending[src]) {
        if (cb) {
          nt = setInterval(function () {
            if (pending[src]) { return console.log('still loading', src, '...') }
            clearInterval(nt)
            cb()
          }, 50)
        }
        return
      }
      pending[src] = true
      inc = document.createElement('script')
      // inc.async = "async";
      inc.onload = function () {
        if (!pending[src]) { return }
        delete pending[src]
        cb && setTimeout(cb, 1)
        delete inc.onload
      }
      inc.onerror = function (e) {
        e.preventDefault()
        inc.onload(e)
      }
      inc.onreadystatechange = function () {
        if (!inc.readyState || FINAL_STATES[inc.readyState]) { inc.onload() }
      }
      try {
        inc.src = src
        head.appendChild(inc)
      } catch (e) {
        console.error('Error while including', src, e)
        cb(e)
      }
    },
    /**
     * Loads and returns a JSON resource asynchronously, by including it into the page (not AJAX).
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JSON resource to load.
     * @param {function} cb Callback function, called by the resource's script.
     */
    loadJSONP: function (src, cb) {
      var callbackFct = '__loadjsonp__' + (counter++)
      window[callbackFct] = function () {
        cb.apply(window, arguments)
        delete window[callbackFct]
      }
      this.includeJS(src + (src.indexOf('?') == -1 ? '?' : '&') + 'callback=' + callbackFct, function () {
        // if http request fails (e.g. 404 error / no content)
        setTimeout(window[callbackFct], 10)
      })
    }
  }
}
function Loader () {
  var FINAL_STATES = {'loaded': true, 'complete': true, 4: true}
  var head = document.getElementsByTagName('head')[0]
  var pending = {}
  var counter = 0
  return {
    /**
     * @private
     * @callback dataCallback
     * @memberof Loader.prototype
     * @param {object|string} data JSON object, or string returned by request as `responseText`.
     */
    /**
     * Loads and returns a JSON resource asynchronously, using XMLHttpRequest (AJAX).
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JSON resource to load.
     * @param {dataCallback} cb Callback function with request's data as first parameter.
     */
    loadJSON: function (src, cb) {
      // if (pending[src]) return cb && cb();
      // pending[src] = true;
      // cross-domain ajax call
      var xdr = new window.XMLHttpRequest()
      xdr.onload = function () {
        var data = xdr.responseText
        try {
          data = JSON.parse(data)
        } catch (e) {};
        cb(data)
        // delete pending[src];
      }
      xdr.open('GET', src, true)
      xdr.send()
    },
    /**
     * @private
     * @callback errorCallback
     * @memberof Loader.prototype
     * @param {Error} error Error caught thru the `error` event or `appendChild()` call, if any.
     */
    /**
     * Loads a JavaScript resource into the page.
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JavaScript resource to load into the page.
     * @param {errorCallback} cb Callback function with error as first parameter, if any.
     */
    includeJS: function (src, cb) {
      var inc, nt
      if (pending[src]) {
        if (cb) {
          nt = setInterval(function () {
            if (pending[src]) { return console.log('still loading', src, '...') }
            clearInterval(nt)
            cb()
          }, 50)
        }
        return
      }
      pending[src] = true
      inc = document.createElement('script')
      // inc.async = "async";
      inc.onload = function () {
        if (!pending[src]) { return }
        delete pending[src]
        cb && setTimeout(cb, 1)
        delete inc.onload
      }
      inc.onerror = function (e) {
        e.preventDefault()
        inc.onload(e)
      }
      inc.onreadystatechange = function () {
        if (!inc.readyState || FINAL_STATES[inc.readyState]) { inc.onload() }
      }
      try {
        inc.src = src
        head.appendChild(inc)
      } catch (e) {
        console.error('Error while including', src, e)
        cb(e)
      }
    },
    /**
     * Loads and returns a JSON resource asynchronously, by including it into the page (not AJAX).
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JSON resource to load.
     * @param {function} cb Callback function, called by the resource's script.
     */
    loadJSONP: function (src, cb) {
      var callbackFct = '__loadjsonp__' + (counter++)
      window[callbackFct] = function () {
        cb.apply(window, arguments)
        delete window[callbackFct]
      }
      this.includeJS(src + (src.indexOf('?') == -1 ? '?' : '&') + 'callback=' + callbackFct, function () {
        // if http request fails (e.g. 404 error / no content)
        setTimeout(window[callbackFct], 10)
      })
    }
  }
}
function Loader ( ) { var FINAL_STATES = { 'loaded' : true , 'complete' : true , 4 : true } var head = document . getElementsByTagName ( 'head' ) [ 0 ] var pending = { } var counter = 0 return { /**
     * @private
     * @callback dataCallback
     * @memberof Loader.prototype
     * @param {object|string} data JSON object, or string returned by request as `responseText`.
     */ /**
     * Loads and returns a JSON resource asynchronously, using XMLHttpRequest (AJAX).
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JSON resource to load.
     * @param {dataCallback} cb Callback function with request's data as first parameter.
     */ loadJSON : function ( src , cb ) { // if (pending[src]) return cb && cb(); // pending[src] = true; // cross-domain ajax call var xdr = new window . XMLHttpRequest ( ) xdr . onload = function ( ) { var data = xdr . responseText try { data = JSON . parse ( data ) } catch ( e ) { } ; cb ( data ) // delete pending[src]; } xdr . open ( 'GET' , src , true ) xdr . send ( ) } , /**
     * @private
     * @callback errorCallback
     * @memberof Loader.prototype
     * @param {Error} error Error caught thru the `error` event or `appendChild()` call, if any.
     */ /**
     * Loads a JavaScript resource into the page.
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JavaScript resource to load into the page.
     * @param {errorCallback} cb Callback function with error as first parameter, if any.
     */ includeJS : function ( src , cb ) { var inc , nt if ( pending [ src ] ) { if ( cb ) { nt = setInterval ( function ( ) { if ( pending [ src ] ) { return console . log ( 'still loading' , src , '...' ) } clearInterval ( nt ) cb ( ) } , 50 ) } return } pending [ src ] = true inc = document . createElement ( 'script' ) // inc.async = "async"; inc . onload = function ( ) { if ( ! pending [ src ] ) { return } delete pending [ src ] cb && setTimeout ( cb , 1 ) delete inc . onload } inc . onerror = function ( e ) { e . preventDefault ( ) inc . onload ( e ) } inc . onreadystatechange = function ( ) { if ( ! inc . readyState || FINAL_STATES [ inc . readyState ] ) { inc . onload ( ) } } try { inc . src = src head . appendChild ( inc ) } catch ( e ) { console . error ( 'Error while including' , src , e ) cb ( e ) } } , /**
     * Loads and returns a JSON resource asynchronously, by including it into the page (not AJAX).
     * @memberof Loader.prototype
     * @param {string} src HTTP(S) URL of the JSON resource to load.
     * @param {function} cb Callback function, called by the resource's script.
     */ loadJSONP : function ( src , cb ) { var callbackFct = '__loadjsonp__' + ( counter ++ ) window [ callbackFct ] = function ( ) { cb . apply ( window , arguments ) delete window [ callbackFct ] } this . includeJS ( src + ( src . indexOf ( '?' ) == - 1 ? '?' : '&' ) + 'callback=' + callbackFct , function ( ) { // if http request fails (e.g. 404 error / no content) setTimeout ( window [ callbackFct ] , 10 ) } ) } } }
This class provides helpers to load JavaScript resources and JSON data.
@class Loader
This class provides helpers to load JavaScript resources and JSON data .