diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/Angular.js | 2 | ||||
| -rw-r--r-- | src/Injector.js | 139 | 
2 files changed, 140 insertions, 1 deletions
diff --git a/src/Angular.js b/src/Angular.js index 29199f9b..bbd43d3b 100644 --- a/src/Angular.js +++ b/src/Angular.js @@ -948,7 +948,7 @@ function angularInit(config, document){    if (autobind) {      var element = isString(autobind) ? document.getElementById(autobind) : document, -        injector = createInjector(), +        injector = createInjector(angularService),          scope = injector('$rootScope');      injector('$compile')(element)(scope); diff --git a/src/Injector.js b/src/Injector.js index 624246af..fe0cc5e9 100644 --- a/src/Injector.js +++ b/src/Injector.js @@ -154,3 +154,142 @@ function inferInjectionArgs(fn) {    }    return fn.$inject;  } + +/////////////////////////////////////// +function createInjector2(modulesToLoad, moduleRegistry) { +  var cache = {}, +      $injector = internalInjector(cache), +      providerSuffix = 'Provider', +      providerSuffixLength = providerSuffix.length; + +  function $provide(name) { +    var provider = cache['#' + name + providerSuffix]; +    if (provider) { +      return provider; +    } else { +      throw Error("No provider for: " + name); +    } +  } + +  $provide.service = function(name, provider) { +    if (isFunction(provider)){ +      provider = $injector.instantiate(provider); +    } +    if (!provider.$get) { +      throw Error('Providers must define $get factory method.'); +    } +    cache['#' + name + providerSuffix] = provider; +  }; +  $provide.factory = function(name, factoryFn) { $provide.service(name, { $get:factoryFn }); }; +  $provide.value = function(name, value) { $provide.factory(name, valueFn(value)); }; + +  $provide.value('$injector', $injector); +  $provide.value('$provide', $provide); + +  function internalInjector(cache) { +    var path = []; + +    function injector(value) { +      switch(typeof value) { +        case 'function': +          return invoke(null, value); +        case 'string': +          var instanceKey = '#' + value; +          if (cache[instanceKey]) { +            return cache[instanceKey]; +          } +          try { +            path.unshift(value); +            var providerKey = instanceKey + providerSuffix, +                provider = cache[providerKey]; +            if (provider) { +              return cache[instanceKey] = invoke(provider, provider.$get); +            } else { +              throw Error("Unknown provider for '" + path.join("' <- '") + "'."); +            } +          } finally { +            path.shift(); +          } +        case 'object': +          if (value instanceof Array) { +            return invoke(null, value); +          } +        default: +          throw Error('Injector expects name or function.'); +      } +    } + +    function invoke(self, fn){ +      var args = [], +          $inject, +          length; + +      switch(typeof fn){ +        case 'function': +          $inject = inferInjectionArgs(fn); +          length = $inject.length; +          break; +        case 'object': +          if (typeof fn.length == 'number') { +            $inject = fn; +            length = $inject.length; +            fn = $inject[--length]; +          } +        default: +          assertArgFn(fn, 'fn'); +      }; + +      while(length--) { +        args.unshift(injector($inject[length], path)); +      } + +      switch (self ? -1 : args.length) { +        case  0: return fn(); +        case  1: return fn(args[0]); +        case  2: return fn(args[0], args[1]); +        case  3: return fn(args[0], args[1], args[2]); +        case  4: return fn(args[0], args[1], args[2], args[3]); +        case  5: return fn(args[0], args[1], args[2], args[3], args[4]); +        case  6: return fn(args[0], args[1], args[2], args[3], args[4], args[5]); +        case  7: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); +        case  8: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7]); +        case  9: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8]); +        case 10: return fn(args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7], args[8], args[9]); +        default: return fn.apply(self, args); +      } +    }; + +    injector.invoke = invoke; +    injector.instantiate = function(Type, locals){ +      var Constructor = function(){}, +          instance; +      Constructor.prototype = Type.prototype; +      instance = new Constructor(); +      return invoke(instance, Type, locals) || instance; +    }; +    return injector; +  } + + +  forEach(modulesToLoad, function(module){ +    if (isString(module)) { +      module = moduleRegistry[module]; +    } +    if (isFunction(module) || isArray(module)) { +      $injector(module); +    } else { +      assertArgFn(module, 'module'); +    } +  }); + +  // instantiate $eager providers +  // for perf we can't do forEach +  for(var name in cache) { +    var index = name.indexOf(providerSuffix); +    if (index  == name.length - providerSuffixLength  && cache[name].$eager) { +      $injector(name.substring(1, index)); +    } +  } + +  return $injector; +}  | 
