src/services/loadable-manager.js
function(src) {
    var _deferred = $q.defer();

    // Instance
    var _loadable = {

      src: src,

      // Loading completion flag
      isComplete: false,

      promise: _deferred.promise,

      // TODO switch to $document
      $element: document.createElement('script')
    };

    // Build DOM element
    _loadable.$element.src = src;
    _loadable.$element.type = 'text/javascript';
    _loadable.$element.async = false;

    _head.insertBefore(_loadable.$element, _head.firstChild);

    // Mark loading in progress
    _loadingList.push(_loadable);

    // Completion
    _loadable.$element.onload = _loadable.$element.onreadystatechange = function() {

      if(!_loadable.isComplete && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) {
        _loadable.isComplete = true;
        _loadable.$element.onload = _loadable.$element.onreadystatechange = null;
        
        if(_head && _loadable.$element.parentNode) {
          _head.removeChild(_loadable.$element);
        }

        // Mark complete
        var i = _loadingList.indexOf(_loadable);
        if(i !== -1) {
          _loadingList.splice(i, 1);
        }
        _completedList.push(_loadable);

        _deferred.resolve(_loadable);
      }
    };

    return _loadable;
  }
function(src) {
    var _deferred = $q.defer();

    // Instance
    var _loadable = {

      src: src,

      // Loading completion flag
      isComplete: false,

      promise: _deferred.promise,

      // TODO switch to $document
      $element: document.createElement('script')
    };

    // Build DOM element
    _loadable.$element.src = src;
    _loadable.$element.type = 'text/javascript';
    _loadable.$element.async = false;

    _head.insertBefore(_loadable.$element, _head.firstChild);

    // Mark loading in progress
    _loadingList.push(_loadable);

    // Completion
    _loadable.$element.onload = _loadable.$element.onreadystatechange = function() {

      if(!_loadable.isComplete && (!this.readyState || this.readyState === "loaded" || this.readyState === "complete")) {
        _loadable.isComplete = true;
        _loadable.$element.onload = _loadable.$element.onreadystatechange = null;
        
        if(_head && _loadable.$element.parentNode) {
          _head.removeChild(_loadable.$element);
        }

        // Mark complete
        var i = _loadingList.indexOf(_loadable);
        if(i !== -1) {
          _loadingList.splice(i, 1);
        }
        _completedList.push(_loadable);

        _deferred.resolve(_loadable);
      }
    };

    return _loadable;
  }
function ( src ) { var _deferred = $q . defer ( ) ; // Instance var _loadable = { src : src , // Loading completion flag isComplete : false , promise : _deferred . promise , // TODO switch to $document $element : document . createElement ( 'script' ) } ; // Build DOM element _loadable . $element . src = src ; _loadable . $element . type = 'text/javascript' ; _loadable . $element . async = false ; _head . insertBefore ( _loadable . $element , _head . firstChild ) ; // Mark loading in progress _loadingList . push ( _loadable ) ; // Completion _loadable . $element . onload = _loadable . $element . onreadystatechange = function ( ) { if ( ! _loadable . isComplete && ( ! this . readyState || this . readyState === "loaded" || this . readyState === "complete" ) ) { _loadable . isComplete = true ; _loadable . $element . onload = _loadable . $element . onreadystatechange = null ; if ( _head && _loadable . $element . parentNode ) { _head . removeChild ( _loadable . $element ) ; } // Mark complete var i = _loadingList . indexOf ( _loadable ) ; if ( i !== - 1 ) { _loadingList . splice ( i , 1 ) ; } _completedList . push ( _loadable ) ; _deferred . resolve ( _loadable ) ; } } ; return _loadable ; }
A loaded resource, adds self to DOM, self manage progress

@return {_Loadable} An instance
A loaded resource adds self to DOM self manage progress