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; +} |
