PageRenderTime 63ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 1ms

/files/angularjs/1.2.3/angular.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 1705 lines | 696 code | 174 blank | 835 comment | 231 complexity | f7b8c2e188ed277185ed80601388bae2 MD5 | raw file
  1. /**
  2. * @license AngularJS v1.2.3
  3. * (c) 2010-2014 Google, Inc. http://angularjs.org
  4. * License: MIT
  5. */
  6. (function(window, document, undefined) {'use strict';
  7. /**
  8. * @description
  9. *
  10. * This object provides a utility for producing rich Error messages within
  11. * Angular. It can be called as follows:
  12. *
  13. * var exampleMinErr = minErr('example');
  14. * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
  15. *
  16. * The above creates an instance of minErr in the example namespace. The
  17. * resulting error will have a namespaced error code of example.one. The
  18. * resulting error will replace {0} with the value of foo, and {1} with the
  19. * value of bar. The object is not restricted in the number of arguments it can
  20. * take.
  21. *
  22. * If fewer arguments are specified than necessary for interpolation, the extra
  23. * interpolation markers will be preserved in the final string.
  24. *
  25. * Since data will be parsed statically during a build step, some restrictions
  26. * are applied with respect to how minErr instances are created and called.
  27. * Instances should have names of the form namespaceMinErr for a minErr created
  28. * using minErr('namespace') . Error codes, namespaces and template strings
  29. * should all be static strings, not variables or general expressions.
  30. *
  31. * @param {string} module The namespace to use for the new minErr instance.
  32. * @returns {function(string, string, ...): Error} instance
  33. */
  34. function minErr(module) {
  35. return function () {
  36. var code = arguments[0],
  37. prefix = '[' + (module ? module + ':' : '') + code + '] ',
  38. template = arguments[1],
  39. templateArgs = arguments,
  40. stringify = function (obj) {
  41. if (typeof obj === 'function') {
  42. return obj.toString().replace(/ \{[\s\S]*$/, '');
  43. } else if (typeof obj === 'undefined') {
  44. return 'undefined';
  45. } else if (typeof obj !== 'string') {
  46. return JSON.stringify(obj);
  47. }
  48. return obj;
  49. },
  50. message, i;
  51. message = prefix + template.replace(/\{\d+\}/g, function (match) {
  52. var index = +match.slice(1, -1), arg;
  53. if (index + 2 < templateArgs.length) {
  54. arg = templateArgs[index + 2];
  55. if (typeof arg === 'function') {
  56. return arg.toString().replace(/ ?\{[\s\S]*$/, '');
  57. } else if (typeof arg === 'undefined') {
  58. return 'undefined';
  59. } else if (typeof arg !== 'string') {
  60. return toJson(arg);
  61. }
  62. return arg;
  63. }
  64. return match;
  65. });
  66. message = message + '\nhttp://errors.angularjs.org/1.2.3/' +
  67. (module ? module + '/' : '') + code;
  68. for (i = 2; i < arguments.length; i++) {
  69. message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
  70. encodeURIComponent(stringify(arguments[i]));
  71. }
  72. return new Error(message);
  73. };
  74. }
  75. /* We need to tell jshint what variables are being exported */
  76. /* global
  77. -angular,
  78. -msie,
  79. -jqLite,
  80. -jQuery,
  81. -slice,
  82. -push,
  83. -toString,
  84. -ngMinErr,
  85. -_angular,
  86. -angularModule,
  87. -nodeName_,
  88. -uid,
  89. -lowercase,
  90. -uppercase,
  91. -manualLowercase,
  92. -manualUppercase,
  93. -nodeName_,
  94. -isArrayLike,
  95. -forEach,
  96. -sortedKeys,
  97. -forEachSorted,
  98. -reverseParams,
  99. -nextUid,
  100. -setHashKey,
  101. -extend,
  102. -int,
  103. -inherit,
  104. -noop,
  105. -identity,
  106. -valueFn,
  107. -isUndefined,
  108. -isDefined,
  109. -isObject,
  110. -isString,
  111. -isNumber,
  112. -isDate,
  113. -isArray,
  114. -isFunction,
  115. -isRegExp,
  116. -isWindow,
  117. -isScope,
  118. -isFile,
  119. -isBoolean,
  120. -trim,
  121. -isElement,
  122. -makeMap,
  123. -map,
  124. -size,
  125. -includes,
  126. -indexOf,
  127. -arrayRemove,
  128. -isLeafNode,
  129. -copy,
  130. -shallowCopy,
  131. -equals,
  132. -csp,
  133. -concat,
  134. -sliceArgs,
  135. -bind,
  136. -toJsonReplacer,
  137. -toJson,
  138. -fromJson,
  139. -toBoolean,
  140. -startingTag,
  141. -tryDecodeURIComponent,
  142. -parseKeyValue,
  143. -toKeyValue,
  144. -encodeUriSegment,
  145. -encodeUriQuery,
  146. -angularInit,
  147. -bootstrap,
  148. -snake_case,
  149. -bindJQuery,
  150. -assertArg,
  151. -assertArgFn,
  152. -assertNotHasOwnProperty,
  153. -getter,
  154. -getBlockElements,
  155. */
  156. ////////////////////////////////////
  157. /**
  158. * @ngdoc function
  159. * @name angular.lowercase
  160. * @function
  161. *
  162. * @description Converts the specified string to lowercase.
  163. * @param {string} string String to be converted to lowercase.
  164. * @returns {string} Lowercased string.
  165. */
  166. var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
  167. /**
  168. * @ngdoc function
  169. * @name angular.uppercase
  170. * @function
  171. *
  172. * @description Converts the specified string to uppercase.
  173. * @param {string} string String to be converted to uppercase.
  174. * @returns {string} Uppercased string.
  175. */
  176. var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
  177. var manualLowercase = function(s) {
  178. /* jshint bitwise: false */
  179. return isString(s)
  180. ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
  181. : s;
  182. };
  183. var manualUppercase = function(s) {
  184. /* jshint bitwise: false */
  185. return isString(s)
  186. ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
  187. : s;
  188. };
  189. // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
  190. // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
  191. // with correct but slower alternatives.
  192. if ('i' !== 'I'.toLowerCase()) {
  193. lowercase = manualLowercase;
  194. uppercase = manualUppercase;
  195. }
  196. var /** holds major version number for IE or NaN for real browsers */
  197. msie,
  198. jqLite, // delay binding since jQuery could be loaded after us.
  199. jQuery, // delay binding
  200. slice = [].slice,
  201. push = [].push,
  202. toString = Object.prototype.toString,
  203. ngMinErr = minErr('ng'),
  204. _angular = window.angular,
  205. /** @name angular */
  206. angular = window.angular || (window.angular = {}),
  207. angularModule,
  208. nodeName_,
  209. uid = ['0', '0', '0'];
  210. /**
  211. * IE 11 changed the format of the UserAgent string.
  212. * See http://msdn.microsoft.com/en-us/library/ms537503.aspx
  213. */
  214. msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
  215. if (isNaN(msie)) {
  216. msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
  217. }
  218. /**
  219. * @private
  220. * @param {*} obj
  221. * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
  222. * String ...)
  223. */
  224. function isArrayLike(obj) {
  225. if (obj == null || isWindow(obj)) {
  226. return false;
  227. }
  228. var length = obj.length;
  229. if (obj.nodeType === 1 && length) {
  230. return true;
  231. }
  232. return isString(obj) || isArray(obj) || length === 0 ||
  233. typeof length === 'number' && length > 0 && (length - 1) in obj;
  234. }
  235. /**
  236. * @ngdoc function
  237. * @name angular.forEach
  238. * @function
  239. *
  240. * @description
  241. * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
  242. * object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value`
  243. * is the value of an object property or an array element and `key` is the object property key or
  244. * array element index. Specifying a `context` for the function is optional.
  245. *
  246. * Note: this function was previously known as `angular.foreach`.
  247. *
  248. <pre>
  249. var values = {name: 'misko', gender: 'male'};
  250. var log = [];
  251. angular.forEach(values, function(value, key){
  252. this.push(key + ': ' + value);
  253. }, log);
  254. expect(log).toEqual(['name: misko', 'gender:male']);
  255. </pre>
  256. *
  257. * @param {Object|Array} obj Object to iterate over.
  258. * @param {Function} iterator Iterator function.
  259. * @param {Object=} context Object to become context (`this`) for the iterator function.
  260. * @returns {Object|Array} Reference to `obj`.
  261. */
  262. function forEach(obj, iterator, context) {
  263. var key;
  264. if (obj) {
  265. if (isFunction(obj)){
  266. for (key in obj) {
  267. if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
  268. iterator.call(context, obj[key], key);
  269. }
  270. }
  271. } else if (obj.forEach && obj.forEach !== forEach) {
  272. obj.forEach(iterator, context);
  273. } else if (isArrayLike(obj)) {
  274. for (key = 0; key < obj.length; key++)
  275. iterator.call(context, obj[key], key);
  276. } else {
  277. for (key in obj) {
  278. if (obj.hasOwnProperty(key)) {
  279. iterator.call(context, obj[key], key);
  280. }
  281. }
  282. }
  283. }
  284. return obj;
  285. }
  286. function sortedKeys(obj) {
  287. var keys = [];
  288. for (var key in obj) {
  289. if (obj.hasOwnProperty(key)) {
  290. keys.push(key);
  291. }
  292. }
  293. return keys.sort();
  294. }
  295. function forEachSorted(obj, iterator, context) {
  296. var keys = sortedKeys(obj);
  297. for ( var i = 0; i < keys.length; i++) {
  298. iterator.call(context, obj[keys[i]], keys[i]);
  299. }
  300. return keys;
  301. }
  302. /**
  303. * when using forEach the params are value, key, but it is often useful to have key, value.
  304. * @param {function(string, *)} iteratorFn
  305. * @returns {function(*, string)}
  306. */
  307. function reverseParams(iteratorFn) {
  308. return function(value, key) { iteratorFn(key, value); };
  309. }
  310. /**
  311. * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
  312. * characters such as '012ABC'. The reason why we are not using simply a number counter is that
  313. * the number string gets longer over time, and it can also overflow, where as the nextId
  314. * will grow much slower, it is a string, and it will never overflow.
  315. *
  316. * @returns an unique alpha-numeric string
  317. */
  318. function nextUid() {
  319. var index = uid.length;
  320. var digit;
  321. while(index) {
  322. index--;
  323. digit = uid[index].charCodeAt(0);
  324. if (digit == 57 /*'9'*/) {
  325. uid[index] = 'A';
  326. return uid.join('');
  327. }
  328. if (digit == 90 /*'Z'*/) {
  329. uid[index] = '0';
  330. } else {
  331. uid[index] = String.fromCharCode(digit + 1);
  332. return uid.join('');
  333. }
  334. }
  335. uid.unshift('0');
  336. return uid.join('');
  337. }
  338. /**
  339. * Set or clear the hashkey for an object.
  340. * @param obj object
  341. * @param h the hashkey (!truthy to delete the hashkey)
  342. */
  343. function setHashKey(obj, h) {
  344. if (h) {
  345. obj.$$hashKey = h;
  346. }
  347. else {
  348. delete obj.$$hashKey;
  349. }
  350. }
  351. /**
  352. * @ngdoc function
  353. * @name angular.extend
  354. * @function
  355. *
  356. * @description
  357. * Extends the destination object `dst` by copying all of the properties from the `src` object(s)
  358. * to `dst`. You can specify multiple `src` objects.
  359. *
  360. * @param {Object} dst Destination object.
  361. * @param {...Object} src Source object(s).
  362. * @returns {Object} Reference to `dst`.
  363. */
  364. function extend(dst) {
  365. var h = dst.$$hashKey;
  366. forEach(arguments, function(obj){
  367. if (obj !== dst) {
  368. forEach(obj, function(value, key){
  369. dst[key] = value;
  370. });
  371. }
  372. });
  373. setHashKey(dst,h);
  374. return dst;
  375. }
  376. function int(str) {
  377. return parseInt(str, 10);
  378. }
  379. function inherit(parent, extra) {
  380. return extend(new (extend(function() {}, {prototype:parent}))(), extra);
  381. }
  382. /**
  383. * @ngdoc function
  384. * @name angular.noop
  385. * @function
  386. *
  387. * @description
  388. * A function that performs no operations. This function can be useful when writing code in the
  389. * functional style.
  390. <pre>
  391. function foo(callback) {
  392. var result = calculateResult();
  393. (callback || angular.noop)(result);
  394. }
  395. </pre>
  396. */
  397. function noop() {}
  398. noop.$inject = [];
  399. /**
  400. * @ngdoc function
  401. * @name angular.identity
  402. * @function
  403. *
  404. * @description
  405. * A function that returns its first argument. This function is useful when writing code in the
  406. * functional style.
  407. *
  408. <pre>
  409. function transformer(transformationFn, value) {
  410. return (transformationFn || angular.identity)(value);
  411. };
  412. </pre>
  413. */
  414. function identity($) {return $;}
  415. identity.$inject = [];
  416. function valueFn(value) {return function() {return value;};}
  417. /**
  418. * @ngdoc function
  419. * @name angular.isUndefined
  420. * @function
  421. *
  422. * @description
  423. * Determines if a reference is undefined.
  424. *
  425. * @param {*} value Reference to check.
  426. * @returns {boolean} True if `value` is undefined.
  427. */
  428. function isUndefined(value){return typeof value == 'undefined';}
  429. /**
  430. * @ngdoc function
  431. * @name angular.isDefined
  432. * @function
  433. *
  434. * @description
  435. * Determines if a reference is defined.
  436. *
  437. * @param {*} value Reference to check.
  438. * @returns {boolean} True if `value` is defined.
  439. */
  440. function isDefined(value){return typeof value != 'undefined';}
  441. /**
  442. * @ngdoc function
  443. * @name angular.isObject
  444. * @function
  445. *
  446. * @description
  447. * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
  448. * considered to be objects.
  449. *
  450. * @param {*} value Reference to check.
  451. * @returns {boolean} True if `value` is an `Object` but not `null`.
  452. */
  453. function isObject(value){return value != null && typeof value == 'object';}
  454. /**
  455. * @ngdoc function
  456. * @name angular.isString
  457. * @function
  458. *
  459. * @description
  460. * Determines if a reference is a `String`.
  461. *
  462. * @param {*} value Reference to check.
  463. * @returns {boolean} True if `value` is a `String`.
  464. */
  465. function isString(value){return typeof value == 'string';}
  466. /**
  467. * @ngdoc function
  468. * @name angular.isNumber
  469. * @function
  470. *
  471. * @description
  472. * Determines if a reference is a `Number`.
  473. *
  474. * @param {*} value Reference to check.
  475. * @returns {boolean} True if `value` is a `Number`.
  476. */
  477. function isNumber(value){return typeof value == 'number';}
  478. /**
  479. * @ngdoc function
  480. * @name angular.isDate
  481. * @function
  482. *
  483. * @description
  484. * Determines if a value is a date.
  485. *
  486. * @param {*} value Reference to check.
  487. * @returns {boolean} True if `value` is a `Date`.
  488. */
  489. function isDate(value){
  490. return toString.apply(value) == '[object Date]';
  491. }
  492. /**
  493. * @ngdoc function
  494. * @name angular.isArray
  495. * @function
  496. *
  497. * @description
  498. * Determines if a reference is an `Array`.
  499. *
  500. * @param {*} value Reference to check.
  501. * @returns {boolean} True if `value` is an `Array`.
  502. */
  503. function isArray(value) {
  504. return toString.apply(value) == '[object Array]';
  505. }
  506. /**
  507. * @ngdoc function
  508. * @name angular.isFunction
  509. * @function
  510. *
  511. * @description
  512. * Determines if a reference is a `Function`.
  513. *
  514. * @param {*} value Reference to check.
  515. * @returns {boolean} True if `value` is a `Function`.
  516. */
  517. function isFunction(value){return typeof value == 'function';}
  518. /**
  519. * Determines if a value is a regular expression object.
  520. *
  521. * @private
  522. * @param {*} value Reference to check.
  523. * @returns {boolean} True if `value` is a `RegExp`.
  524. */
  525. function isRegExp(value) {
  526. return toString.apply(value) == '[object RegExp]';
  527. }
  528. /**
  529. * Checks if `obj` is a window object.
  530. *
  531. * @private
  532. * @param {*} obj Object to check
  533. * @returns {boolean} True if `obj` is a window obj.
  534. */
  535. function isWindow(obj) {
  536. return obj && obj.document && obj.location && obj.alert && obj.setInterval;
  537. }
  538. function isScope(obj) {
  539. return obj && obj.$evalAsync && obj.$watch;
  540. }
  541. function isFile(obj) {
  542. return toString.apply(obj) === '[object File]';
  543. }
  544. function isBoolean(value) {
  545. return typeof value == 'boolean';
  546. }
  547. var trim = (function() {
  548. // native trim is way faster: http://jsperf.com/angular-trim-test
  549. // but IE doesn't have it... :-(
  550. // TODO: we should move this into IE/ES5 polyfill
  551. if (!String.prototype.trim) {
  552. return function(value) {
  553. return isString(value) ? value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : value;
  554. };
  555. }
  556. return function(value) {
  557. return isString(value) ? value.trim() : value;
  558. };
  559. })();
  560. /**
  561. * @ngdoc function
  562. * @name angular.isElement
  563. * @function
  564. *
  565. * @description
  566. * Determines if a reference is a DOM element (or wrapped jQuery element).
  567. *
  568. * @param {*} value Reference to check.
  569. * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
  570. */
  571. function isElement(node) {
  572. return node &&
  573. (node.nodeName // we are a direct element
  574. || (node.on && node.find)); // we have an on and find method part of jQuery API
  575. }
  576. /**
  577. * @param str 'key1,key2,...'
  578. * @returns {object} in the form of {key1:true, key2:true, ...}
  579. */
  580. function makeMap(str){
  581. var obj = {}, items = str.split(","), i;
  582. for ( i = 0; i < items.length; i++ )
  583. obj[ items[i] ] = true;
  584. return obj;
  585. }
  586. if (msie < 9) {
  587. nodeName_ = function(element) {
  588. element = element.nodeName ? element : element[0];
  589. return (element.scopeName && element.scopeName != 'HTML')
  590. ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
  591. };
  592. } else {
  593. nodeName_ = function(element) {
  594. return element.nodeName ? element.nodeName : element[0].nodeName;
  595. };
  596. }
  597. function map(obj, iterator, context) {
  598. var results = [];
  599. forEach(obj, function(value, index, list) {
  600. results.push(iterator.call(context, value, index, list));
  601. });
  602. return results;
  603. }
  604. /**
  605. * @description
  606. * Determines the number of elements in an array, the number of properties an object has, or
  607. * the length of a string.
  608. *
  609. * Note: This function is used to augment the Object type in Angular expressions. See
  610. * {@link angular.Object} for more information about Angular arrays.
  611. *
  612. * @param {Object|Array|string} obj Object, array, or string to inspect.
  613. * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object
  614. * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array.
  615. */
  616. function size(obj, ownPropsOnly) {
  617. var count = 0, key;
  618. if (isArray(obj) || isString(obj)) {
  619. return obj.length;
  620. } else if (isObject(obj)){
  621. for (key in obj)
  622. if (!ownPropsOnly || obj.hasOwnProperty(key))
  623. count++;
  624. }
  625. return count;
  626. }
  627. function includes(array, obj) {
  628. return indexOf(array, obj) != -1;
  629. }
  630. function indexOf(array, obj) {
  631. if (array.indexOf) return array.indexOf(obj);
  632. for ( var i = 0; i < array.length; i++) {
  633. if (obj === array[i]) return i;
  634. }
  635. return -1;
  636. }
  637. function arrayRemove(array, value) {
  638. var index = indexOf(array, value);
  639. if (index >=0)
  640. array.splice(index, 1);
  641. return value;
  642. }
  643. function isLeafNode (node) {
  644. if (node) {
  645. switch (node.nodeName) {
  646. case "OPTION":
  647. case "PRE":
  648. case "TITLE":
  649. return true;
  650. }
  651. }
  652. return false;
  653. }
  654. /**
  655. * @ngdoc function
  656. * @name angular.copy
  657. * @function
  658. *
  659. * @description
  660. * Creates a deep copy of `source`, which should be an object or an array.
  661. *
  662. * * If no destination is supplied, a copy of the object or array is created.
  663. * * If a destination is provided, all of its elements (for array) or properties (for objects)
  664. * are deleted and then all elements/properties from the source are copied to it.
  665. * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
  666. * * If `source` is identical to 'destination' an exception will be thrown.
  667. *
  668. * @param {*} source The source that will be used to make a copy.
  669. * Can be any type, including primitives, `null`, and `undefined`.
  670. * @param {(Object|Array)=} destination Destination into which the source is copied. If
  671. * provided, must be of the same type as `source`.
  672. * @returns {*} The copy or updated `destination`, if `destination` was specified.
  673. *
  674. * @example
  675. <doc:example>
  676. <doc:source>
  677. <div ng-controller="Controller">
  678. <form novalidate class="simple-form">
  679. Name: <input type="text" ng-model="user.name" /><br />
  680. E-mail: <input type="email" ng-model="user.email" /><br />
  681. Gender: <input type="radio" ng-model="user.gender" value="male" />male
  682. <input type="radio" ng-model="user.gender" value="female" />female<br />
  683. <button ng-click="reset()">RESET</button>
  684. <button ng-click="update(user)">SAVE</button>
  685. </form>
  686. <pre>form = {{user | json}}</pre>
  687. <pre>master = {{master | json}}</pre>
  688. </div>
  689. <script>
  690. function Controller($scope) {
  691. $scope.master= {};
  692. $scope.update = function(user) {
  693. // Example with 1 argument
  694. $scope.master= angular.copy(user);
  695. };
  696. $scope.reset = function() {
  697. // Example with 2 arguments
  698. angular.copy($scope.master, $scope.user);
  699. };
  700. $scope.reset();
  701. }
  702. </script>
  703. </doc:source>
  704. </doc:example>
  705. */
  706. function copy(source, destination){
  707. if (isWindow(source) || isScope(source)) {
  708. throw ngMinErr('cpws',
  709. "Can't copy! Making copies of Window or Scope instances is not supported.");
  710. }
  711. if (!destination) {
  712. destination = source;
  713. if (source) {
  714. if (isArray(source)) {
  715. destination = copy(source, []);
  716. } else if (isDate(source)) {
  717. destination = new Date(source.getTime());
  718. } else if (isRegExp(source)) {
  719. destination = new RegExp(source.source);
  720. } else if (isObject(source)) {
  721. destination = copy(source, {});
  722. }
  723. }
  724. } else {
  725. if (source === destination) throw ngMinErr('cpi',
  726. "Can't copy! Source and destination are identical.");
  727. if (isArray(source)) {
  728. destination.length = 0;
  729. for ( var i = 0; i < source.length; i++) {
  730. destination.push(copy(source[i]));
  731. }
  732. } else {
  733. var h = destination.$$hashKey;
  734. forEach(destination, function(value, key){
  735. delete destination[key];
  736. });
  737. for ( var key in source) {
  738. destination[key] = copy(source[key]);
  739. }
  740. setHashKey(destination,h);
  741. }
  742. }
  743. return destination;
  744. }
  745. /**
  746. * Create a shallow copy of an object
  747. */
  748. function shallowCopy(src, dst) {
  749. dst = dst || {};
  750. for(var key in src) {
  751. // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
  752. // so we don't need to worry hasOwnProperty here
  753. if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
  754. dst[key] = src[key];
  755. }
  756. }
  757. return dst;
  758. }
  759. /**
  760. * @ngdoc function
  761. * @name angular.equals
  762. * @function
  763. *
  764. * @description
  765. * Determines if two objects or two values are equivalent. Supports value types, regular
  766. * expressions, arrays and objects.
  767. *
  768. * Two objects or values are considered equivalent if at least one of the following is true:
  769. *
  770. * * Both objects or values pass `===` comparison.
  771. * * Both objects or values are of the same type and all of their properties are equal by
  772. * comparing them with `angular.equals`.
  773. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
  774. * * Both values represent the same regular expression (In JavasScript,
  775. * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
  776. * representation matches).
  777. *
  778. * During a property comparison, properties of `function` type and properties with names
  779. * that begin with `$` are ignored.
  780. *
  781. * Scope and DOMWindow objects are being compared only by identify (`===`).
  782. *
  783. * @param {*} o1 Object or value to compare.
  784. * @param {*} o2 Object or value to compare.
  785. * @returns {boolean} True if arguments are equal.
  786. */
  787. function equals(o1, o2) {
  788. if (o1 === o2) return true;
  789. if (o1 === null || o2 === null) return false;
  790. if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
  791. var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
  792. if (t1 == t2) {
  793. if (t1 == 'object') {
  794. if (isArray(o1)) {
  795. if (!isArray(o2)) return false;
  796. if ((length = o1.length) == o2.length) {
  797. for(key=0; key<length; key++) {
  798. if (!equals(o1[key], o2[key])) return false;
  799. }
  800. return true;
  801. }
  802. } else if (isDate(o1)) {
  803. return isDate(o2) && o1.getTime() == o2.getTime();
  804. } else if (isRegExp(o1) && isRegExp(o2)) {
  805. return o1.toString() == o2.toString();
  806. } else {
  807. if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) || isArray(o2)) return false;
  808. keySet = {};
  809. for(key in o1) {
  810. if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
  811. if (!equals(o1[key], o2[key])) return false;
  812. keySet[key] = true;
  813. }
  814. for(key in o2) {
  815. if (!keySet.hasOwnProperty(key) &&
  816. key.charAt(0) !== '$' &&
  817. o2[key] !== undefined &&
  818. !isFunction(o2[key])) return false;
  819. }
  820. return true;
  821. }
  822. }
  823. }
  824. return false;
  825. }
  826. function csp() {
  827. return (document.securityPolicy && document.securityPolicy.isActive) ||
  828. (document.querySelector &&
  829. !!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]')));
  830. }
  831. function concat(array1, array2, index) {
  832. return array1.concat(slice.call(array2, index));
  833. }
  834. function sliceArgs(args, startIndex) {
  835. return slice.call(args, startIndex || 0);
  836. }
  837. /* jshint -W101 */
  838. /**
  839. * @ngdoc function
  840. * @name angular.bind
  841. * @function
  842. *
  843. * @description
  844. * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
  845. * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
  846. * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
  847. * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
  848. *
  849. * @param {Object} self Context which `fn` should be evaluated in.
  850. * @param {function()} fn Function to be bound.
  851. * @param {...*} args Optional arguments to be prebound to the `fn` function call.
  852. * @returns {function()} Function that wraps the `fn` with all the specified bindings.
  853. */
  854. /* jshint +W101 */
  855. function bind(self, fn) {
  856. var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
  857. if (isFunction(fn) && !(fn instanceof RegExp)) {
  858. return curryArgs.length
  859. ? function() {
  860. return arguments.length
  861. ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0)))
  862. : fn.apply(self, curryArgs);
  863. }
  864. : function() {
  865. return arguments.length
  866. ? fn.apply(self, arguments)
  867. : fn.call(self);
  868. };
  869. } else {
  870. // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
  871. return fn;
  872. }
  873. }
  874. function toJsonReplacer(key, value) {
  875. var val = value;
  876. if (typeof key === 'string' && key.charAt(0) === '$') {
  877. val = undefined;
  878. } else if (isWindow(value)) {
  879. val = '$WINDOW';
  880. } else if (value && document === value) {
  881. val = '$DOCUMENT';
  882. } else if (isScope(value)) {
  883. val = '$SCOPE';
  884. }
  885. return val;
  886. }
  887. /**
  888. * @ngdoc function
  889. * @name angular.toJson
  890. * @function
  891. *
  892. * @description
  893. * Serializes input into a JSON-formatted string. Properties with leading $ characters will be
  894. * stripped since angular uses this notation internally.
  895. *
  896. * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
  897. * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
  898. * @returns {string|undefined} JSON-ified string representing `obj`.
  899. */
  900. function toJson(obj, pretty) {
  901. if (typeof obj === 'undefined') return undefined;
  902. return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
  903. }
  904. /**
  905. * @ngdoc function
  906. * @name angular.fromJson
  907. * @function
  908. *
  909. * @description
  910. * Deserializes a JSON string.
  911. *
  912. * @param {string} json JSON string to deserialize.
  913. * @returns {Object|Array|Date|string|number} Deserialized thingy.
  914. */
  915. function fromJson(json) {
  916. return isString(json)
  917. ? JSON.parse(json)
  918. : json;
  919. }
  920. function toBoolean(value) {
  921. if (value && value.length !== 0) {
  922. var v = lowercase("" + value);
  923. value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
  924. } else {
  925. value = false;
  926. }
  927. return value;
  928. }
  929. /**
  930. * @returns {string} Returns the string representation of the element.
  931. */
  932. function startingTag(element) {
  933. element = jqLite(element).clone();
  934. try {
  935. // turns out IE does not let you set .html() on elements which
  936. // are not allowed to have children. So we just ignore it.
  937. element.html('');
  938. } catch(e) {}
  939. // As Per DOM Standards
  940. var TEXT_NODE = 3;
  941. var elemHtml = jqLite('<div>').append(element).html();
  942. try {
  943. return element[0].nodeType === TEXT_NODE ? lowercase(elemHtml) :
  944. elemHtml.
  945. match(/^(<[^>]+>)/)[1].
  946. replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
  947. } catch(e) {
  948. return lowercase(elemHtml);
  949. }
  950. }
  951. /////////////////////////////////////////////////
  952. /**
  953. * Tries to decode the URI component without throwing an exception.
  954. *
  955. * @private
  956. * @param str value potential URI component to check.
  957. * @returns {boolean} True if `value` can be decoded
  958. * with the decodeURIComponent function.
  959. */
  960. function tryDecodeURIComponent(value) {
  961. try {
  962. return decodeURIComponent(value);
  963. } catch(e) {
  964. // Ignore any invalid uri component
  965. }
  966. }
  967. /**
  968. * Parses an escaped url query string into key-value pairs.
  969. * @returns Object.<(string|boolean)>
  970. */
  971. function parseKeyValue(/**string*/keyValue) {
  972. var obj = {}, key_value, key;
  973. forEach((keyValue || "").split('&'), function(keyValue){
  974. if ( keyValue ) {
  975. key_value = keyValue.split('=');
  976. key = tryDecodeURIComponent(key_value[0]);
  977. if ( isDefined(key) ) {
  978. var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
  979. if (!obj[key]) {
  980. obj[key] = val;
  981. } else if(isArray(obj[key])) {
  982. obj[key].push(val);
  983. } else {
  984. obj[key] = [obj[key],val];
  985. }
  986. }
  987. }
  988. });
  989. return obj;
  990. }
  991. function toKeyValue(obj) {
  992. var parts = [];
  993. forEach(obj, function(value, key) {
  994. if (isArray(value)) {
  995. forEach(value, function(arrayValue) {
  996. parts.push(encodeUriQuery(key, true) +
  997. (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
  998. });
  999. } else {
  1000. parts.push(encodeUriQuery(key, true) +
  1001. (value === true ? '' : '=' + encodeUriQuery(value, true)));
  1002. }
  1003. });
  1004. return parts.length ? parts.join('&') : '';
  1005. }
  1006. /**
  1007. * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
  1008. * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
  1009. * segments:
  1010. * segment = *pchar
  1011. * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  1012. * pct-encoded = "%" HEXDIG HEXDIG
  1013. * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  1014. * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
  1015. * / "*" / "+" / "," / ";" / "="
  1016. */
  1017. function encodeUriSegment(val) {
  1018. return encodeUriQuery(val, true).
  1019. replace(/%26/gi, '&').
  1020. replace(/%3D/gi, '=').
  1021. replace(/%2B/gi, '+');
  1022. }
  1023. /**
  1024. * This method is intended for encoding *key* or *value* parts of query component. We need a custom
  1025. * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
  1026. * encoded per http://tools.ietf.org/html/rfc3986:
  1027. * query = *( pchar / "/" / "?" )
  1028. * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  1029. * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  1030. * pct-encoded = "%" HEXDIG HEXDIG
  1031. * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
  1032. * / "*" / "+" / "," / ";" / "="
  1033. */
  1034. function encodeUriQuery(val, pctEncodeSpaces) {
  1035. return encodeURIComponent(val).
  1036. replace(/%40/gi, '@').
  1037. replace(/%3A/gi, ':').
  1038. replace(/%24/g, '$').
  1039. replace(/%2C/gi, ',').
  1040. replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
  1041. }
  1042. /**
  1043. * @ngdoc directive
  1044. * @name ng.directive:ngApp
  1045. *
  1046. * @element ANY
  1047. * @param {angular.Module} ngApp an optional application
  1048. * {@link angular.module module} name to load.
  1049. *
  1050. * @description
  1051. *
  1052. * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
  1053. * designates the **root element** of the application and is typically placed near the root element
  1054. * of the page - e.g. on the `<body>` or `<html>` tags.
  1055. *
  1056. * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
  1057. * found in the document will be used to define the root element to auto-bootstrap as an
  1058. * application. To run multiple applications in an HTML document you must manually bootstrap them using
  1059. * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
  1060. *
  1061. * You can specify an **AngularJS module** to be used as the root module for the application. This
  1062. * module will be loaded into the {@link AUTO.$injector} when the application is bootstrapped and
  1063. * should contain the application code needed or have dependencies on other modules that will
  1064. * contain the code. See {@link angular.module} for more information.
  1065. *
  1066. * In the example below if the `ngApp` directive were not placed on the `html` element then the
  1067. * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
  1068. * would not be resolved to `3`.
  1069. *
  1070. * `ngApp` is the easiest, and most common, way to bootstrap an application.
  1071. *
  1072. <example module="ngAppDemo">
  1073. <file name="index.html">
  1074. <div ng-controller="ngAppDemoController">
  1075. I can add: {{a}} + {{b}} = {{ a+b }}
  1076. </file>
  1077. <file name="script.js">
  1078. angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
  1079. $scope.a = 1;
  1080. $scope.b = 2;
  1081. });
  1082. </file>
  1083. </example>
  1084. *
  1085. */
  1086. function angularInit(element, bootstrap) {
  1087. var elements = [element],
  1088. appElement,
  1089. module,
  1090. names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
  1091. NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
  1092. function append(element) {
  1093. element && elements.push(element);
  1094. }
  1095. forEach(names, function(name) {
  1096. names[name] = true;
  1097. append(document.getElementById(name));
  1098. name = name.replace(':', '\\:');
  1099. if (element.querySelectorAll) {
  1100. forEach(element.querySelectorAll('.' + name), append);
  1101. forEach(element.querySelectorAll('.' + name + '\\:'), append);
  1102. forEach(element.querySelectorAll('[' + name + ']'), append);
  1103. }
  1104. });
  1105. forEach(elements, function(element) {
  1106. if (!appElement) {
  1107. var className = ' ' + element.className + ' ';
  1108. var match = NG_APP_CLASS_REGEXP.exec(className);
  1109. if (match) {
  1110. appElement = element;
  1111. module = (match[2] || '').replace(/\s+/g, ',');
  1112. } else {
  1113. forEach(element.attributes, function(attr) {
  1114. if (!appElement && names[attr.name]) {
  1115. appElement = element;
  1116. module = attr.value;
  1117. }
  1118. });
  1119. }
  1120. }
  1121. });
  1122. if (appElement) {
  1123. bootstrap(appElement, module ? [module] : []);
  1124. }
  1125. }
  1126. /**
  1127. * @ngdoc function
  1128. * @name angular.bootstrap
  1129. * @description
  1130. * Use this function to manually start up angular application.
  1131. *
  1132. * See: {@link guide/bootstrap Bootstrap}
  1133. *
  1134. * Note that ngScenario-based end-to-end tests cannot use this function to bootstrap manually.
  1135. * They must use {@link api/ng.directive:ngApp ngApp}.
  1136. *
  1137. * @param {Element} element DOM element which is the root of angular application.
  1138. * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
  1139. * Each item in the array should be the name of a predefined module or a (DI annotated)
  1140. * function that will be invoked by the injector as a run block.
  1141. * See: {@link angular.module modules}
  1142. * @returns {AUTO.$injector} Returns the newly created injector for this app.
  1143. */
  1144. function bootstrap(element, modules) {
  1145. var doBootstrap = function() {
  1146. element = jqLite(element);
  1147. if (element.injector()) {
  1148. var tag = (element[0] === document) ? 'document' : startingTag(element);
  1149. throw ngMinErr('btstrpd', "App Already Bootstrapped with this Element '{0}'", tag);
  1150. }
  1151. modules = modules || [];
  1152. modules.unshift(['$provide', function($provide) {
  1153. $provide.value('$rootElement', element);
  1154. }]);
  1155. modules.unshift('ng');
  1156. var injector = createInjector(modules);
  1157. injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector', '$animate',
  1158. function(scope, element, compile, injector, animate) {
  1159. scope.$apply(function() {
  1160. element.data('$injector', injector);
  1161. compile(element)(scope);
  1162. });
  1163. }]
  1164. );
  1165. return injector;
  1166. };
  1167. var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
  1168. if (window && !NG_DEFER_BOOTSTRAP.test(window.name)) {
  1169. return doBootstrap();
  1170. }
  1171. window.name = window.name.replace(NG_DEFER_BOOTSTRAP, '');
  1172. angular.resumeBootstrap = function(extraModules) {
  1173. forEach(extraModules, function(module) {
  1174. modules.push(module);
  1175. });
  1176. doBootstrap();
  1177. };
  1178. }
  1179. var SNAKE_CASE_REGEXP = /[A-Z]/g;
  1180. function snake_case(name, separator){
  1181. separator = separator || '_';
  1182. return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
  1183. return (pos ? separator : '') + letter.toLowerCase();
  1184. });
  1185. }
  1186. function bindJQuery() {
  1187. // bind to jQuery if present;
  1188. jQuery = window.jQuery;
  1189. // reset to jQuery or default to us.
  1190. if (jQuery) {
  1191. jqLite = jQuery;
  1192. extend(jQuery.fn, {
  1193. scope: JQLitePrototype.scope,
  1194. isolateScope: JQLitePrototype.isolateScope,
  1195. controller: JQLitePrototype.controller,
  1196. injector: JQLitePrototype.injector,
  1197. inheritedData: JQLitePrototype.inheritedData
  1198. });
  1199. // Method signature:
  1200. // jqLitePatchJQueryRemove(name, dispatchThis, filterElems, getterIfNoArguments)
  1201. jqLitePatchJQueryRemove('remove', true, true, false);
  1202. jqLitePatchJQueryRemove('empty', false, false, false);
  1203. jqLitePatchJQueryRemove('html', false, false, true);
  1204. } else {
  1205. jqLite = JQLite;
  1206. }
  1207. angular.element = jqLite;
  1208. }
  1209. /**
  1210. * throw error if the argument is falsy.
  1211. */
  1212. function assertArg(arg, name, reason) {
  1213. if (!arg) {
  1214. throw ngMinErr('areq', "Argument '{0}' is {1}", (name || '?'), (reason || "required"));
  1215. }
  1216. return arg;
  1217. }
  1218. function assertArgFn(arg, name, acceptArrayAnnotation) {
  1219. if (acceptArrayAnnotation && isArray(arg)) {
  1220. arg = arg[arg.length - 1];
  1221. }
  1222. assertArg(isFunction(arg), name, 'not a function, got ' +
  1223. (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg));
  1224. return arg;
  1225. }
  1226. /**
  1227. * throw error if the name given is hasOwnProperty
  1228. * @param {String} name the name to test
  1229. * @param {String} context the context in which the name is used, such as module or directive
  1230. */
  1231. function assertNotHasOwnProperty(name, context) {
  1232. if (name === 'hasOwnProperty') {
  1233. throw ngMinErr('badname', "hasOwnProperty is not a valid {0} name", context);
  1234. }
  1235. }
  1236. /**
  1237. * Return the value accessible from the object by path. Any undefined traversals are ignored
  1238. * @param {Object} obj starting object
  1239. * @param {string} path path to traverse
  1240. * @param {boolean=true} bindFnToScope
  1241. * @returns value as accessible by path
  1242. */
  1243. //TODO(misko): this function needs to be removed
  1244. function getter(obj, path, bindFnToScope) {
  1245. if (!path) return obj;
  1246. var keys = path.split('.');
  1247. var key;
  1248. var lastInstance = obj;
  1249. var len = keys.length;
  1250. for (var i = 0; i < len; i++) {
  1251. key = keys[i];
  1252. if (obj) {
  1253. obj = (lastInstance = obj)[key];
  1254. }
  1255. }
  1256. if (!bindFnToScope && isFunction(obj)) {
  1257. return bind(lastInstance, obj);
  1258. }
  1259. return obj;
  1260. }
  1261. /**
  1262. * Return the siblings between `startNode` and `endNode`, inclusive
  1263. * @param {Object} object with `startNode` and `endNode` properties
  1264. * @returns jQlite object containing the elements
  1265. */
  1266. function getBlockElements(block) {
  1267. if (block.startNode === block.endNode) {
  1268. return jqLite(block.startNode);
  1269. }
  1270. var element = block.startNode;
  1271. var elements = [element];
  1272. do {
  1273. element = element.nextSibling;
  1274. if (!element) break;
  1275. elements.push(element);
  1276. } while (element !== block.endNode);
  1277. return jqLite(elements);
  1278. }
  1279. /**
  1280. * @ngdoc interface
  1281. * @name angular.Module
  1282. * @description
  1283. *
  1284. * Interface for configuring angular {@link angular.module modules}.
  1285. */
  1286. function setupModuleLoader(window) {
  1287. var $injectorMinErr = minErr('$injector');
  1288. var ngMinErr = minErr('ng');
  1289. function ensure(obj, name, factory) {
  1290. return obj[name] || (obj[name] = factory());
  1291. }
  1292. var angular = ensure(window, 'angular', Object);
  1293. // We need to expose `angular.$$minErr` to modules such as `ngResource` that reference it during bootstrap
  1294. angular.$$minErr = angular.$$minErr || minErr;
  1295. return ensure(angular, 'module', function() {
  1296. /** @type {Object.<string, angular.Module>} */
  1297. var modules = {};
  1298. /**
  1299. * @ngdoc function
  1300. * @name angular.module
  1301. * @description
  1302. *
  1303. * The `angular.module` is a global place for creating, registering and retrieving Angular
  1304. * modules.
  1305. * All modules (angular core or 3rd party) that should be available to an application must be
  1306. * registered using this mechanism.
  1307. *
  1308. * When passed two or more arguments, a new module is created. If passed only one argument, an
  1309. * existing module (the name passed as the first argument to `module`) is retrieved.
  1310. *
  1311. *
  1312. * # Module
  1313. *
  1314. * A module is a collection of services, directives, filters, and configuration information.
  1315. * `angular.module` is used to configure the {@link AUTO.$injector $injector}.
  1316. *
  1317. * <pre>
  1318. * // Create a new module
  1319. * var myModule = angular.module('myModule', []);
  1320. *
  1321. * // register a new service
  1322. * myModule.value('appName', 'MyCoolApp');
  1323. *
  1324. * // configure existing services inside initialization blocks.
  1325. * myModule.config(function($locationProvider) {
  1326. * // Configure existing providers
  1327. * $locationProvider.hashPrefix('!');
  1328. * });
  1329. * </pre>
  1330. *
  1331. * Then you can create an injector and load your modules like this:
  1332. *
  1333. * <pre>
  1334. * var injector = angular.injector(['ng', 'MyModule'])
  1335. * </pre>
  1336. *
  1337. * However it's more likely that you'll just use
  1338. * {@link ng.directive:ngApp ngApp} or
  1339. * {@link angular.bootstrap} to simplify this process for you.
  1340. *
  1341. * @param {!string} name The name of the module to create or retrieve.
  1342. * @param {Array.<string>=} requires If specified then new module is being created. If
  1343. * unspecified then the the module is being retrieved for further configuration.
  1344. * @param {Function} configFn Optional configuration function for the module. Same as
  1345. * {@link angular.Module#methods_config Module#config()}.
  1346. * @returns {module} new module with the {@link angular.Module} api.
  1347. */
  1348. return function module(name, requires, configFn) {
  1349. var assertNotHasOwnProperty = function(name, context) {
  1350. if (name === 'hasOwnProperty') {
  1351. throw ngMinErr('badname', 'hasOwnProperty is not a valid {0} name', context);
  1352. }
  1353. };
  1354. assertNotHasOwnProperty(name, 'module');
  1355. if (requires && modules.hasOwnProperty(name)) {
  1356. modules[name] = null;
  1357. }
  1358. return ensure(modules, name, function() {
  1359. if (!requires) {
  1360. throw $injectorMinErr('nomod', "Module '{0}' is not available! You either misspelled " +
  1361. "the module name or forgot to load it. If registering a module ensure that you " +
  1362. "specify the dependencies as the second argument.", name);
  1363. }
  1364. /** @type {!Array.<Array.<*>>} */
  1365. var invokeQueue = [];
  1366. /** @type {!Array.<Function>} */
  1367. var runBlocks = [];
  1368. var config = invokeLater('$injector', 'invoke');
  1369. /** @type {angular.Module} */
  1370. var moduleInstance = {
  1371. // Private state
  1372. _invokeQueue: invokeQueue,
  1373. _runBlocks: runBlocks,
  1374. /**
  1375. * @ngdoc property
  1376. * @name angular.Module#requires
  1377. * @propertyOf angular.Module
  1378. * @returns {Array.<string>} List of module names which must be loaded before this module.
  1379. * @description
  1380. * Holds the list of modules which the injector will load before the current module is
  1381. * loaded.
  1382. */
  1383. requires: requires,
  1384. /**
  1385. * @ngdoc property
  1386. * @name angular.Module#name
  1387. * @propertyOf angular.Module
  1388. * @returns {string} Name of the module.
  1389. * @description
  1390. */
  1391. name: name,
  1392. /**
  1393. * @ngdoc method
  1394. * @name angular.Module#provider
  1395. * @methodOf angular.Module
  1396. * @param {string} name service name
  1397. * @param {Function} providerType Construction function for creating new instance of the
  1398. * service.
  1399. * @description
  1400. * See {@link AUTO.$provide#provider $provide.provider()}.
  1401. */
  1402. provider: invokeLater('$provide', 'provider'),
  1403. /**
  1404. * @ngdoc method
  1405. * @name angular.Module#factory
  1406. * @methodOf angular.Module
  1407. * @param {string} name service name
  1408. * @param {Function} providerFunction Function for creating new instance of the service.
  1409. * @description
  1410. * See {@link AUTO.$provide#factory $provide.factory()}.
  1411. */
  1412. factory: invokeLater('$provide', 'factory'),
  1413. /**
  1414. * @ngdoc method
  1415. * @name angular.Module#service
  1416. * @methodOf angular.Module
  1417. * @param {string} name service name
  1418. * @param {Function} constructor A constructor function that will be instantiated.
  1419. * @description
  1420. * See {@link AUTO.$provide#service $provide.service()}.
  1421. */
  1422. service: invokeLater('$provide', 'service'),
  1423. /**
  1424. * @ngdoc method
  1425. * @name angular.Module#value
  1426. * @methodOf angular.Module
  1427. * @param {string} name service name
  1428. * @param {*} object Service instance object.
  1429. * @description
  1430. * See {@link AUTO.$provide#value $provide.value()}.
  1431. */
  1432. value: invokeLater('$provide', 'value'),
  1433. /**
  1434. * @ngdoc method
  1435. * @name angular.Module#constant
  1436. * @methodOf angular.Module
  1437. * @param {string} name constant name
  1438. * @param {*} object Constant value.
  1439. * @description
  1440. * Because the constant are fixed, they get applied before other provide methods.
  1441. * See {@link AUTO.$provide#constant $provide.constant()}.
  1442. */
  1443. constant: invokeLater('$provide', 'constant', 'unshift'),
  1444. /**
  1445. * @ngdoc method
  1446. * @name angular.Module#animation
  1447. * @methodOf angular.Module
  1448. * @param {string} name animation name
  1449. * @param {Function} animationFactory Factory function for creating new instance of an
  1450. * animation.
  1451. * @description
  1452. *
  1453. * **NOTE**: animations take effect only if the **ngAnimate** module is loaded.
  1454. *
  1455. *
  1456. * Defines an animation hook that can be later used with
  1457. * {@link ngAnimate.$animate $animate} service and directives that use this service.
  1458. *
  1459. * <pre>
  1460. * module.animation('.animation-name', function($inject1, $inject2) {
  1461. * return {
  1462. * eventName : function(element, done) {
  1463. * //code to run the animation
  1464. * //once complete, then run done()
  1465. * return function cancellationFunction(element) {
  1466. * //code to cancel the animation
  1467. * }
  1468. * }
  1469. * }
  1470. * })
  1471. * </pre>
  1472. *
  1473. * See {@link ngAnimate.$animateProvider#register $animateProvider.register()} and
  1474. * {@link ngAnimate ngAnimate module} for more information.
  1475. */
  1476. animation: invokeLater('$animateProvider', 'register'),
  1477. /**
  1478. * @ngdoc method
  1479. * @name angular.Module#filter
  1480. * @methodOf angular.Module
  1481. * @param {string} name Filter name.
  1482. * @param {Function} filterFactory Factory function for creating new instance of filter.
  1483. * @description
  1484. * See {@link ng.$filterProvider#register $filterProvider.register()}.
  1485. */
  1486. filter: invokeLater('$filterProvider', 'register'),
  1487. /**
  1488. * @ngdoc method
  1489. * @name angular.Module#controller
  1490. * @methodOf angular.Module
  1491. * @param {string|Object} name Controller name, or an object map of controllers where the
  1492. * keys are the names and the values are the constructors.
  1493. * @param {Function} constructor Controller constructor function.
  1494. * @description
  1495. * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
  1496. */
  1497. controller: invokeLater('$controllerProvider', 'register'),
  1498. /**
  1499. * @ngdoc method
  1500. * @name angular.Module#directive
  1501. * @methodOf angular.Module
  1502. * @param {string|Object} name Directive name, or an object map of directives where the
  1503. * keys are the names and the values are the factories.
  1504. * @param {Function} directiveFactory Factory function for creating new instance of
  1505. * directives.
  1506. * @description
  1507. * See {@link ng.$compileProvider#methods_directive $compileProvider.directive()}.
  1508. */
  1509. directive: invokeLater('$compileProvider', 'directive'),
  1510. /**
  1511. * @ngdoc method
  1512. * @name angular.Module#config
  1513. * @methodOf angular.Module
  1514. * @param {Function} configFn Execute this function on module load. Useful for service
  1515. * configuration.
  1516. * @description
  1517. * Use this method to register work which needs to be performed on module loading.
  1518. */
  1519. config: config,
  1520. /**
  1521. * @ngdoc method
  1522. * @name angular.Module#run
  1523. * @methodOf angular.Module
  1524. * @param {Function} initializationFn Execute this function after injector creation.
  1525. * Useful for application init