/** * @license AngularJS * (c) 2010-2012 AngularJS http://angularjs.org * License: MIT */ /** * Backward compatibility module for AngularJS * @author Vojta Jina <vojta.jina@gmail.com> * * Load this module to enable old-style controllers, where controller and scope are mixed together. * * This module decorates Angular's $controller service: * - if given controller does not ask for $scope, it instantiates it in old-way * - if given controller does ask for $scope, instantiation is delegated to default $controller * service. * * This also allows migrating apps step by step. */ angular.module('ngScopeController', ['ng'], ['$provide', function($provide) { $provide.decorator('$controller', ['$injector', '$delegate', '$parse', '$window', function($injector, $delegate, $parse, $window) { var FN_ARGS = /^function\s*[^\(]*\(([^\)]*)\)/m; var FN_ARG_SPLIT = /,/; var FN_ARG = /^\s*(.+?)\s*$/; var STRIP_COMMENTS = /((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg; /** * Return a list of arguments to inject * If no $inject property specified it parse the argument names. * @param fn */ function inferInjectionArgs(fn) { // assert fn is a function if (!angular.isFunction(fn)) { var error = new Error("Controller must be a function, got " + (typeof fn === 'object' ? fn.constructor.name || 'Object' : typeof fn)); throw error; } if (fn.$inject) return fn.$inject; // guess from argument names var args = []; var fnText = fn.toString().replace(STRIP_COMMENTS, ''); var argDecl = fnText.match(FN_ARGS); angular.forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg) { arg.replace(FN_ARG, function(all, name) { args.push(name); }); }); return args; } /** * $controller service * * @param {Function|string} Class Constructor function of the controller or string id. * @param {Object} locals Locals for injecting, must contain a $scope. * @return {Object} Instance of the controller. */ return function(Class, locals) { var scope = locals.$scope; // given string id, find ctrl on window or current scope if (angular.isString(Class)) { var getter = $parse(Class); Class = getter(scope) || getter($window); } var injectArgs = inferInjectionArgs(Class); // IE8 and below does not support Array.indexOf function indexOf(array, obj) { if (array.indexOf) return array.indexOf(obj); for ( var i = 0; i < array.length; i++) { if (obj === array[i]) return i; } return -1; } // asking for scope - delegate to original service if (indexOf(injectArgs, '$scope') !== -1) { return $delegate(Class, locals); } // not asking for scope - BC hack var classPrototype = Class.prototype; for(var key in classPrototype) { scope[key] = angular.bind(scope, classPrototype[key]); } $injector.invoke(Class, scope, locals); return scope; }; }]); }]);