PageRenderTime 68ms CodeModel.GetById 30ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/libs//1.5.0-rc.0/angular.js

https://gitlab.com/Mirros/cdnjs
JavaScript | 1696 lines | 654 code | 174 blank | 868 comment | 210 complexity | 3304b214fad13f7ab89c912ed06feedd MD5 | raw file
  1. /**
  2. * @license AngularJS v1.5.0-rc.0
  3. * (c) 2010-2015 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. * @param {function} ErrorConstructor Custom error constructor to be instantiated when returning
  33. * error from returned function, for cases when a particular type of error is useful.
  34. * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
  35. */
  36. function minErr(module, ErrorConstructor) {
  37. ErrorConstructor = ErrorConstructor || Error;
  38. return function() {
  39. var SKIP_INDEXES = 2;
  40. var templateArgs = arguments,
  41. code = templateArgs[0],
  42. message = '[' + (module ? module + ':' : '') + code + '] ',
  43. template = templateArgs[1],
  44. paramPrefix, i;
  45. message += template.replace(/\{\d+\}/g, function(match) {
  46. var index = +match.slice(1, -1),
  47. shiftedIndex = index + SKIP_INDEXES;
  48. if (shiftedIndex < templateArgs.length) {
  49. return toDebugString(templateArgs[shiftedIndex]);
  50. }
  51. return match;
  52. });
  53. message += '\nhttp://errors.angularjs.org/1.5.0-rc.0/' +
  54. (module ? module + '/' : '') + code;
  55. for (i = SKIP_INDEXES, paramPrefix = '?'; i < templateArgs.length; i++, paramPrefix = '&') {
  56. message += paramPrefix + 'p' + (i - SKIP_INDEXES) + '=' +
  57. encodeURIComponent(toDebugString(templateArgs[i]));
  58. }
  59. return new ErrorConstructor(message);
  60. };
  61. }
  62. /* We need to tell jshint what variables are being exported */
  63. /* global angular: true,
  64. msie: true,
  65. jqLite: true,
  66. jQuery: true,
  67. slice: true,
  68. splice: true,
  69. push: true,
  70. toString: true,
  71. ngMinErr: true,
  72. angularModule: true,
  73. uid: true,
  74. REGEX_STRING_REGEXP: true,
  75. VALIDITY_STATE_PROPERTY: true,
  76. lowercase: true,
  77. uppercase: true,
  78. manualLowercase: true,
  79. manualUppercase: true,
  80. nodeName_: true,
  81. isArrayLike: true,
  82. forEach: true,
  83. forEachSorted: true,
  84. reverseParams: true,
  85. nextUid: true,
  86. setHashKey: true,
  87. extend: true,
  88. toInt: true,
  89. inherit: true,
  90. merge: true,
  91. noop: true,
  92. identity: true,
  93. valueFn: true,
  94. isUndefined: true,
  95. isDefined: true,
  96. isObject: true,
  97. isBlankObject: true,
  98. isString: true,
  99. isNumber: true,
  100. isDate: true,
  101. isArray: true,
  102. isFunction: true,
  103. isRegExp: true,
  104. isWindow: true,
  105. isScope: true,
  106. isFile: true,
  107. isFormData: true,
  108. isBlob: true,
  109. isBoolean: true,
  110. isPromiseLike: true,
  111. trim: true,
  112. escapeForRegexp: true,
  113. isElement: true,
  114. makeMap: true,
  115. includes: true,
  116. arrayRemove: true,
  117. copy: true,
  118. shallowCopy: true,
  119. equals: true,
  120. csp: true,
  121. jq: true,
  122. concat: true,
  123. sliceArgs: true,
  124. bind: true,
  125. toJsonReplacer: true,
  126. toJson: true,
  127. fromJson: true,
  128. convertTimezoneToLocal: true,
  129. timezoneToOffset: true,
  130. startingTag: true,
  131. tryDecodeURIComponent: true,
  132. parseKeyValue: true,
  133. toKeyValue: true,
  134. encodeUriSegment: true,
  135. encodeUriQuery: true,
  136. angularInit: true,
  137. bootstrap: true,
  138. getTestability: true,
  139. snake_case: true,
  140. bindJQuery: true,
  141. assertArg: true,
  142. assertArgFn: true,
  143. assertNotHasOwnProperty: true,
  144. getter: true,
  145. getBlockNodes: true,
  146. hasOwnProperty: true,
  147. createMap: true,
  148. NODE_TYPE_ELEMENT: true,
  149. NODE_TYPE_ATTRIBUTE: true,
  150. NODE_TYPE_TEXT: true,
  151. NODE_TYPE_COMMENT: true,
  152. NODE_TYPE_DOCUMENT: true,
  153. NODE_TYPE_DOCUMENT_FRAGMENT: true,
  154. */
  155. ////////////////////////////////////
  156. /**
  157. * @ngdoc module
  158. * @name ng
  159. * @module ng
  160. * @description
  161. *
  162. * # ng (core module)
  163. * The ng module is loaded by default when an AngularJS application is started. The module itself
  164. * contains the essential components for an AngularJS application to function. The table below
  165. * lists a high level breakdown of each of the services/factories, filters, directives and testing
  166. * components available within this core module.
  167. *
  168. * <div doc-module-components="ng"></div>
  169. */
  170. var REGEX_STRING_REGEXP = /^\/(.+)\/([a-z]*)$/;
  171. // The name of a form control's ValidityState property.
  172. // This is used so that it's possible for internal tests to create mock ValidityStates.
  173. var VALIDITY_STATE_PROPERTY = 'validity';
  174. /**
  175. * @ngdoc function
  176. * @name angular.lowercase
  177. * @module ng
  178. * @kind function
  179. *
  180. * @description Converts the specified string to lowercase.
  181. * @param {string} string String to be converted to lowercase.
  182. * @returns {string} Lowercased string.
  183. */
  184. var lowercase = function(string) {return isString(string) ? string.toLowerCase() : string;};
  185. var hasOwnProperty = Object.prototype.hasOwnProperty;
  186. /**
  187. * @ngdoc function
  188. * @name angular.uppercase
  189. * @module ng
  190. * @kind function
  191. *
  192. * @description Converts the specified string to uppercase.
  193. * @param {string} string String to be converted to uppercase.
  194. * @returns {string} Uppercased string.
  195. */
  196. var uppercase = function(string) {return isString(string) ? string.toUpperCase() : string;};
  197. var manualLowercase = function(s) {
  198. /* jshint bitwise: false */
  199. return isString(s)
  200. ? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
  201. : s;
  202. };
  203. var manualUppercase = function(s) {
  204. /* jshint bitwise: false */
  205. return isString(s)
  206. ? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
  207. : s;
  208. };
  209. // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
  210. // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
  211. // with correct but slower alternatives.
  212. if ('i' !== 'I'.toLowerCase()) {
  213. lowercase = manualLowercase;
  214. uppercase = manualUppercase;
  215. }
  216. var
  217. msie, // holds major version number for IE, or NaN if UA is not IE.
  218. jqLite, // delay binding since jQuery could be loaded after us.
  219. jQuery, // delay binding
  220. slice = [].slice,
  221. splice = [].splice,
  222. push = [].push,
  223. toString = Object.prototype.toString,
  224. getPrototypeOf = Object.getPrototypeOf,
  225. ngMinErr = minErr('ng'),
  226. /** @name angular */
  227. angular = window.angular || (window.angular = {}),
  228. angularModule,
  229. uid = 0;
  230. /**
  231. * documentMode is an IE-only property
  232. * http://msdn.microsoft.com/en-us/library/ie/cc196988(v=vs.85).aspx
  233. */
  234. msie = document.documentMode;
  235. /**
  236. * @private
  237. * @param {*} obj
  238. * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
  239. * String ...)
  240. */
  241. function isArrayLike(obj) {
  242. // `null`, `undefined` and `window` are not array-like
  243. if (obj == null || isWindow(obj)) return false;
  244. // arrays, strings and jQuery/jqLite objects are array like
  245. // * jqLite is either the jQuery or jqLite constructor function
  246. // * we have to check the existance of jqLite first as this method is called
  247. // via the forEach method when constructing the jqLite object in the first place
  248. if (isArray(obj) || isString(obj) || (jqLite && obj instanceof jqLite)) return true;
  249. // Support: iOS 8.2 (not reproducible in simulator)
  250. // "length" in obj used to prevent JIT error (gh-11508)
  251. var length = "length" in Object(obj) && obj.length;
  252. // NodeList objects (with `item` method) and
  253. // other objects with suitable length characteristics are array-like
  254. return isNumber(length) &&
  255. (length >= 0 && (length - 1) in obj || typeof obj.item == 'function');
  256. }
  257. /**
  258. * @ngdoc function
  259. * @name angular.forEach
  260. * @module ng
  261. * @kind function
  262. *
  263. * @description
  264. * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
  265. * object or an array. The `iterator` function is invoked with `iterator(value, key, obj)`, where `value`
  266. * is the value of an object property or an array element, `key` is the object property key or
  267. * array element index and obj is the `obj` itself. Specifying a `context` for the function is optional.
  268. *
  269. * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
  270. * using the `hasOwnProperty` method.
  271. *
  272. * Unlike ES262's
  273. * [Array.prototype.forEach](http://www.ecma-international.org/ecma-262/5.1/#sec-15.4.4.18),
  274. * Providing 'undefined' or 'null' values for `obj` will not throw a TypeError, but rather just
  275. * return the value provided.
  276. *
  277. ```js
  278. var values = {name: 'misko', gender: 'male'};
  279. var log = [];
  280. angular.forEach(values, function(value, key) {
  281. this.push(key + ': ' + value);
  282. }, log);
  283. expect(log).toEqual(['name: misko', 'gender: male']);
  284. ```
  285. *
  286. * @param {Object|Array} obj Object to iterate over.
  287. * @param {Function} iterator Iterator function.
  288. * @param {Object=} context Object to become context (`this`) for the iterator function.
  289. * @returns {Object|Array} Reference to `obj`.
  290. */
  291. function forEach(obj, iterator, context) {
  292. var key, length;
  293. if (obj) {
  294. if (isFunction(obj)) {
  295. for (key in obj) {
  296. // Need to check if hasOwnProperty exists,
  297. // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
  298. if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
  299. iterator.call(context, obj[key], key, obj);
  300. }
  301. }
  302. } else if (isArray(obj) || isArrayLike(obj)) {
  303. var isPrimitive = typeof obj !== 'object';
  304. for (key = 0, length = obj.length; key < length; key++) {
  305. if (isPrimitive || key in obj) {
  306. iterator.call(context, obj[key], key, obj);
  307. }
  308. }
  309. } else if (obj.forEach && obj.forEach !== forEach) {
  310. obj.forEach(iterator, context, obj);
  311. } else if (isBlankObject(obj)) {
  312. // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
  313. for (key in obj) {
  314. iterator.call(context, obj[key], key, obj);
  315. }
  316. } else if (typeof obj.hasOwnProperty === 'function') {
  317. // Slow path for objects inheriting Object.prototype, hasOwnProperty check needed
  318. for (key in obj) {
  319. if (obj.hasOwnProperty(key)) {
  320. iterator.call(context, obj[key], key, obj);
  321. }
  322. }
  323. } else {
  324. // Slow path for objects which do not have a method `hasOwnProperty`
  325. for (key in obj) {
  326. if (hasOwnProperty.call(obj, key)) {
  327. iterator.call(context, obj[key], key, obj);
  328. }
  329. }
  330. }
  331. }
  332. return obj;
  333. }
  334. function forEachSorted(obj, iterator, context) {
  335. var keys = Object.keys(obj).sort();
  336. for (var i = 0; i < keys.length; i++) {
  337. iterator.call(context, obj[keys[i]], keys[i]);
  338. }
  339. return keys;
  340. }
  341. /**
  342. * when using forEach the params are value, key, but it is often useful to have key, value.
  343. * @param {function(string, *)} iteratorFn
  344. * @returns {function(*, string)}
  345. */
  346. function reverseParams(iteratorFn) {
  347. return function(value, key) { iteratorFn(key, value); };
  348. }
  349. /**
  350. * A consistent way of creating unique IDs in angular.
  351. *
  352. * Using simple numbers allows us to generate 28.6 million unique ids per second for 10 years before
  353. * we hit number precision issues in JavaScript.
  354. *
  355. * Math.pow(2,53) / 60 / 60 / 24 / 365 / 10 = 28.6M
  356. *
  357. * @returns {number} an unique alpha-numeric string
  358. */
  359. function nextUid() {
  360. return ++uid;
  361. }
  362. /**
  363. * Set or clear the hashkey for an object.
  364. * @param obj object
  365. * @param h the hashkey (!truthy to delete the hashkey)
  366. */
  367. function setHashKey(obj, h) {
  368. if (h) {
  369. obj.$$hashKey = h;
  370. } else {
  371. delete obj.$$hashKey;
  372. }
  373. }
  374. function baseExtend(dst, objs, deep) {
  375. var h = dst.$$hashKey;
  376. for (var i = 0, ii = objs.length; i < ii; ++i) {
  377. var obj = objs[i];
  378. if (!isObject(obj) && !isFunction(obj)) continue;
  379. var keys = Object.keys(obj);
  380. for (var j = 0, jj = keys.length; j < jj; j++) {
  381. var key = keys[j];
  382. var src = obj[key];
  383. if (deep && isObject(src)) {
  384. if (isDate(src)) {
  385. dst[key] = new Date(src.valueOf());
  386. } else if (isRegExp(src)) {
  387. dst[key] = new RegExp(src);
  388. } else if (src.nodeName) {
  389. dst[key] = src.cloneNode(true);
  390. } else if (isElement(src)) {
  391. dst[key] = src.clone();
  392. } else {
  393. if (!isObject(dst[key])) dst[key] = isArray(src) ? [] : {};
  394. baseExtend(dst[key], [src], true);
  395. }
  396. } else {
  397. dst[key] = src;
  398. }
  399. }
  400. }
  401. setHashKey(dst, h);
  402. return dst;
  403. }
  404. /**
  405. * @ngdoc function
  406. * @name angular.extend
  407. * @module ng
  408. * @kind function
  409. *
  410. * @description
  411. * Extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
  412. * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
  413. * by passing an empty object as the target: `var object = angular.extend({}, object1, object2)`.
  414. *
  415. * **Note:** Keep in mind that `angular.extend` does not support recursive merge (deep copy). Use
  416. * {@link angular.merge} for this.
  417. *
  418. * @param {Object} dst Destination object.
  419. * @param {...Object} src Source object(s).
  420. * @returns {Object} Reference to `dst`.
  421. */
  422. function extend(dst) {
  423. return baseExtend(dst, slice.call(arguments, 1), false);
  424. }
  425. /**
  426. * @ngdoc function
  427. * @name angular.merge
  428. * @module ng
  429. * @kind function
  430. *
  431. * @description
  432. * Deeply extends the destination object `dst` by copying own enumerable properties from the `src` object(s)
  433. * to `dst`. You can specify multiple `src` objects. If you want to preserve original objects, you can do so
  434. * by passing an empty object as the target: `var object = angular.merge({}, object1, object2)`.
  435. *
  436. * Unlike {@link angular.extend extend()}, `merge()` recursively descends into object properties of source
  437. * objects, performing a deep copy.
  438. *
  439. * @param {Object} dst Destination object.
  440. * @param {...Object} src Source object(s).
  441. * @returns {Object} Reference to `dst`.
  442. */
  443. function merge(dst) {
  444. return baseExtend(dst, slice.call(arguments, 1), true);
  445. }
  446. function toInt(str) {
  447. return parseInt(str, 10);
  448. }
  449. function inherit(parent, extra) {
  450. return extend(Object.create(parent), extra);
  451. }
  452. /**
  453. * @ngdoc function
  454. * @name angular.noop
  455. * @module ng
  456. * @kind function
  457. *
  458. * @description
  459. * A function that performs no operations. This function can be useful when writing code in the
  460. * functional style.
  461. ```js
  462. function foo(callback) {
  463. var result = calculateResult();
  464. (callback || angular.noop)(result);
  465. }
  466. ```
  467. */
  468. function noop() {}
  469. noop.$inject = [];
  470. /**
  471. * @ngdoc function
  472. * @name angular.identity
  473. * @module ng
  474. * @kind function
  475. *
  476. * @description
  477. * A function that returns its first argument. This function is useful when writing code in the
  478. * functional style.
  479. *
  480. ```js
  481. function transformer(transformationFn, value) {
  482. return (transformationFn || angular.identity)(value);
  483. };
  484. ```
  485. * @param {*} value to be returned.
  486. * @returns {*} the value passed in.
  487. */
  488. function identity($) {return $;}
  489. identity.$inject = [];
  490. function valueFn(value) {return function() {return value;};}
  491. function hasCustomToString(obj) {
  492. return isFunction(obj.toString) && obj.toString !== toString;
  493. }
  494. /**
  495. * @ngdoc function
  496. * @name angular.isUndefined
  497. * @module ng
  498. * @kind function
  499. *
  500. * @description
  501. * Determines if a reference is undefined.
  502. *
  503. * @param {*} value Reference to check.
  504. * @returns {boolean} True if `value` is undefined.
  505. */
  506. function isUndefined(value) {return typeof value === 'undefined';}
  507. /**
  508. * @ngdoc function
  509. * @name angular.isDefined
  510. * @module ng
  511. * @kind function
  512. *
  513. * @description
  514. * Determines if a reference is defined.
  515. *
  516. * @param {*} value Reference to check.
  517. * @returns {boolean} True if `value` is defined.
  518. */
  519. function isDefined(value) {return typeof value !== 'undefined';}
  520. /**
  521. * @ngdoc function
  522. * @name angular.isObject
  523. * @module ng
  524. * @kind function
  525. *
  526. * @description
  527. * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
  528. * considered to be objects. Note that JavaScript arrays are objects.
  529. *
  530. * @param {*} value Reference to check.
  531. * @returns {boolean} True if `value` is an `Object` but not `null`.
  532. */
  533. function isObject(value) {
  534. // http://jsperf.com/isobject4
  535. return value !== null && typeof value === 'object';
  536. }
  537. /**
  538. * Determine if a value is an object with a null prototype
  539. *
  540. * @returns {boolean} True if `value` is an `Object` with a null prototype
  541. */
  542. function isBlankObject(value) {
  543. return value !== null && typeof value === 'object' && !getPrototypeOf(value);
  544. }
  545. /**
  546. * @ngdoc function
  547. * @name angular.isString
  548. * @module ng
  549. * @kind function
  550. *
  551. * @description
  552. * Determines if a reference is a `String`.
  553. *
  554. * @param {*} value Reference to check.
  555. * @returns {boolean} True if `value` is a `String`.
  556. */
  557. function isString(value) {return typeof value === 'string';}
  558. /**
  559. * @ngdoc function
  560. * @name angular.isNumber
  561. * @module ng
  562. * @kind function
  563. *
  564. * @description
  565. * Determines if a reference is a `Number`.
  566. *
  567. * This includes the "special" numbers `NaN`, `+Infinity` and `-Infinity`.
  568. *
  569. * If you wish to exclude these then you can use the native
  570. * [`isFinite'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/isFinite)
  571. * method.
  572. *
  573. * @param {*} value Reference to check.
  574. * @returns {boolean} True if `value` is a `Number`.
  575. */
  576. function isNumber(value) {return typeof value === 'number';}
  577. /**
  578. * @ngdoc function
  579. * @name angular.isDate
  580. * @module ng
  581. * @kind function
  582. *
  583. * @description
  584. * Determines if a value is a date.
  585. *
  586. * @param {*} value Reference to check.
  587. * @returns {boolean} True if `value` is a `Date`.
  588. */
  589. function isDate(value) {
  590. return toString.call(value) === '[object Date]';
  591. }
  592. /**
  593. * @ngdoc function
  594. * @name angular.isArray
  595. * @module ng
  596. * @kind function
  597. *
  598. * @description
  599. * Determines if a reference is an `Array`.
  600. *
  601. * @param {*} value Reference to check.
  602. * @returns {boolean} True if `value` is an `Array`.
  603. */
  604. var isArray = Array.isArray;
  605. /**
  606. * @ngdoc function
  607. * @name angular.isFunction
  608. * @module ng
  609. * @kind function
  610. *
  611. * @description
  612. * Determines if a reference is a `Function`.
  613. *
  614. * @param {*} value Reference to check.
  615. * @returns {boolean} True if `value` is a `Function`.
  616. */
  617. function isFunction(value) {return typeof value === 'function';}
  618. /**
  619. * Determines if a value is a regular expression object.
  620. *
  621. * @private
  622. * @param {*} value Reference to check.
  623. * @returns {boolean} True if `value` is a `RegExp`.
  624. */
  625. function isRegExp(value) {
  626. return toString.call(value) === '[object RegExp]';
  627. }
  628. /**
  629. * Checks if `obj` is a window object.
  630. *
  631. * @private
  632. * @param {*} obj Object to check
  633. * @returns {boolean} True if `obj` is a window obj.
  634. */
  635. function isWindow(obj) {
  636. return obj && obj.window === obj;
  637. }
  638. function isScope(obj) {
  639. return obj && obj.$evalAsync && obj.$watch;
  640. }
  641. function isFile(obj) {
  642. return toString.call(obj) === '[object File]';
  643. }
  644. function isFormData(obj) {
  645. return toString.call(obj) === '[object FormData]';
  646. }
  647. function isBlob(obj) {
  648. return toString.call(obj) === '[object Blob]';
  649. }
  650. function isBoolean(value) {
  651. return typeof value === 'boolean';
  652. }
  653. function isPromiseLike(obj) {
  654. return obj && isFunction(obj.then);
  655. }
  656. var TYPED_ARRAY_REGEXP = /^\[object (?:Uint8|Uint8Clamped|Uint16|Uint32|Int8|Int16|Int32|Float32|Float64)Array\]$/;
  657. function isTypedArray(value) {
  658. return value && isNumber(value.length) && TYPED_ARRAY_REGEXP.test(toString.call(value));
  659. }
  660. var trim = function(value) {
  661. return isString(value) ? value.trim() : value;
  662. };
  663. // Copied from:
  664. // http://docs.closure-library.googlecode.com/git/local_closure_goog_string_string.js.source.html#line1021
  665. // Prereq: s is a string.
  666. var escapeForRegexp = function(s) {
  667. return s.replace(/([-()\[\]{}+?*.$\^|,:#<!\\])/g, '\\$1').
  668. replace(/\x08/g, '\\x08');
  669. };
  670. /**
  671. * @ngdoc function
  672. * @name angular.isElement
  673. * @module ng
  674. * @kind function
  675. *
  676. * @description
  677. * Determines if a reference is a DOM element (or wrapped jQuery element).
  678. *
  679. * @param {*} value Reference to check.
  680. * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
  681. */
  682. function isElement(node) {
  683. return !!(node &&
  684. (node.nodeName // we are a direct element
  685. || (node.prop && node.attr && node.find))); // we have an on and find method part of jQuery API
  686. }
  687. /**
  688. * @param str 'key1,key2,...'
  689. * @returns {object} in the form of {key1:true, key2:true, ...}
  690. */
  691. function makeMap(str) {
  692. var obj = {}, items = str.split(","), i;
  693. for (i = 0; i < items.length; i++) {
  694. obj[items[i]] = true;
  695. }
  696. return obj;
  697. }
  698. function nodeName_(element) {
  699. return lowercase(element.nodeName || (element[0] && element[0].nodeName));
  700. }
  701. function includes(array, obj) {
  702. return Array.prototype.indexOf.call(array, obj) != -1;
  703. }
  704. function arrayRemove(array, value) {
  705. var index = array.indexOf(value);
  706. if (index >= 0) {
  707. array.splice(index, 1);
  708. }
  709. return index;
  710. }
  711. /**
  712. * @ngdoc function
  713. * @name angular.copy
  714. * @module ng
  715. * @kind function
  716. *
  717. * @description
  718. * Creates a deep copy of `source`, which should be an object or an array.
  719. *
  720. * * If no destination is supplied, a copy of the object or array is created.
  721. * * If a destination is provided, all of its elements (for arrays) or properties (for objects)
  722. * are deleted and then all elements/properties from the source are copied to it.
  723. * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
  724. * * If `source` is identical to 'destination' an exception will be thrown.
  725. *
  726. * @param {*} source The source that will be used to make a copy.
  727. * Can be any type, including primitives, `null`, and `undefined`.
  728. * @param {(Object|Array)=} destination Destination into which the source is copied. If
  729. * provided, must be of the same type as `source`.
  730. * @returns {*} The copy or updated `destination`, if `destination` was specified.
  731. *
  732. * @example
  733. <example module="copyExample">
  734. <file name="index.html">
  735. <div ng-controller="ExampleController">
  736. <form novalidate class="simple-form">
  737. Name: <input type="text" ng-model="user.name" /><br />
  738. E-mail: <input type="email" ng-model="user.email" /><br />
  739. Gender: <input type="radio" ng-model="user.gender" value="male" />male
  740. <input type="radio" ng-model="user.gender" value="female" />female<br />
  741. <button ng-click="reset()">RESET</button>
  742. <button ng-click="update(user)">SAVE</button>
  743. </form>
  744. <pre>form = {{user | json}}</pre>
  745. <pre>master = {{master | json}}</pre>
  746. </div>
  747. <script>
  748. angular.module('copyExample', [])
  749. .controller('ExampleController', ['$scope', function($scope) {
  750. $scope.master= {};
  751. $scope.update = function(user) {
  752. // Example with 1 argument
  753. $scope.master= angular.copy(user);
  754. };
  755. $scope.reset = function() {
  756. // Example with 2 arguments
  757. angular.copy($scope.master, $scope.user);
  758. };
  759. $scope.reset();
  760. }]);
  761. </script>
  762. </file>
  763. </example>
  764. */
  765. function copy(source, destination) {
  766. var stackSource = [];
  767. var stackDest = [];
  768. if (destination) {
  769. if (isTypedArray(destination)) {
  770. throw ngMinErr('cpta', "Can't copy! TypedArray destination cannot be mutated.");
  771. }
  772. if (source === destination) {
  773. throw ngMinErr('cpi', "Can't copy! Source and destination are identical.");
  774. }
  775. // Empty the destination object
  776. if (isArray(destination)) {
  777. destination.length = 0;
  778. } else {
  779. forEach(destination, function(value, key) {
  780. if (key !== '$$hashKey') {
  781. delete destination[key];
  782. }
  783. });
  784. }
  785. stackSource.push(source);
  786. stackDest.push(destination);
  787. return copyRecurse(source, destination);
  788. }
  789. return copyElement(source);
  790. function copyRecurse(source, destination) {
  791. var h = destination.$$hashKey;
  792. var result, key;
  793. if (isArray(source)) {
  794. for (var i = 0, ii = source.length; i < ii; i++) {
  795. destination.push(copyElement(source[i]));
  796. }
  797. } else if (isBlankObject(source)) {
  798. // createMap() fast path --- Safe to avoid hasOwnProperty check because prototype chain is empty
  799. for (key in source) {
  800. destination[key] = copyElement(source[key]);
  801. }
  802. } else if (source && typeof source.hasOwnProperty === 'function') {
  803. // Slow path, which must rely on hasOwnProperty
  804. for (key in source) {
  805. if (source.hasOwnProperty(key)) {
  806. destination[key] = copyElement(source[key]);
  807. }
  808. }
  809. } else {
  810. // Slowest path --- hasOwnProperty can't be called as a method
  811. for (key in source) {
  812. if (hasOwnProperty.call(source, key)) {
  813. destination[key] = copyElement(source[key]);
  814. }
  815. }
  816. }
  817. setHashKey(destination, h);
  818. return destination;
  819. }
  820. function copyElement(source) {
  821. // Simple values
  822. if (!isObject(source)) {
  823. return source;
  824. }
  825. // Already copied values
  826. var index = stackSource.indexOf(source);
  827. if (index !== -1) {
  828. return stackDest[index];
  829. }
  830. if (isWindow(source) || isScope(source)) {
  831. throw ngMinErr('cpws',
  832. "Can't copy! Making copies of Window or Scope instances is not supported.");
  833. }
  834. var needsRecurse = false;
  835. var destination;
  836. if (isArray(source)) {
  837. destination = [];
  838. needsRecurse = true;
  839. } else if (isTypedArray(source)) {
  840. destination = new source.constructor(source);
  841. } else if (isDate(source)) {
  842. destination = new Date(source.getTime());
  843. } else if (isRegExp(source)) {
  844. destination = new RegExp(source.source, source.toString().match(/[^\/]*$/)[0]);
  845. destination.lastIndex = source.lastIndex;
  846. } else if (isFunction(source.cloneNode)) {
  847. destination = source.cloneNode(true);
  848. } else {
  849. destination = Object.create(getPrototypeOf(source));
  850. needsRecurse = true;
  851. }
  852. stackSource.push(source);
  853. stackDest.push(destination);
  854. return needsRecurse
  855. ? copyRecurse(source, destination)
  856. : destination;
  857. }
  858. }
  859. /**
  860. * Creates a shallow copy of an object, an array or a primitive.
  861. *
  862. * Assumes that there are no proto properties for objects.
  863. */
  864. function shallowCopy(src, dst) {
  865. if (isArray(src)) {
  866. dst = dst || [];
  867. for (var i = 0, ii = src.length; i < ii; i++) {
  868. dst[i] = src[i];
  869. }
  870. } else if (isObject(src)) {
  871. dst = dst || {};
  872. for (var key in src) {
  873. if (!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
  874. dst[key] = src[key];
  875. }
  876. }
  877. }
  878. return dst || src;
  879. }
  880. /**
  881. * @ngdoc function
  882. * @name angular.equals
  883. * @module ng
  884. * @kind function
  885. *
  886. * @description
  887. * Determines if two objects or two values are equivalent. Supports value types, regular
  888. * expressions, arrays and objects.
  889. *
  890. * Two objects or values are considered equivalent if at least one of the following is true:
  891. *
  892. * * Both objects or values pass `===` comparison.
  893. * * Both objects or values are of the same type and all of their properties are equal by
  894. * comparing them with `angular.equals`.
  895. * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
  896. * * Both values represent the same regular expression (In JavaScript,
  897. * /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
  898. * representation matches).
  899. *
  900. * During a property comparison, properties of `function` type and properties with names
  901. * that begin with `$` are ignored.
  902. *
  903. * Scope and DOMWindow objects are being compared only by identify (`===`).
  904. *
  905. * @param {*} o1 Object or value to compare.
  906. * @param {*} o2 Object or value to compare.
  907. * @returns {boolean} True if arguments are equal.
  908. */
  909. function equals(o1, o2) {
  910. if (o1 === o2) return true;
  911. if (o1 === null || o2 === null) return false;
  912. if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
  913. var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
  914. if (t1 == t2) {
  915. if (t1 == 'object') {
  916. if (isArray(o1)) {
  917. if (!isArray(o2)) return false;
  918. if ((length = o1.length) == o2.length) {
  919. for (key = 0; key < length; key++) {
  920. if (!equals(o1[key], o2[key])) return false;
  921. }
  922. return true;
  923. }
  924. } else if (isDate(o1)) {
  925. if (!isDate(o2)) return false;
  926. return equals(o1.getTime(), o2.getTime());
  927. } else if (isRegExp(o1)) {
  928. return isRegExp(o2) ? o1.toString() == o2.toString() : false;
  929. } else {
  930. if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2) ||
  931. isArray(o2) || isDate(o2) || isRegExp(o2)) return false;
  932. keySet = createMap();
  933. for (key in o1) {
  934. if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
  935. if (!equals(o1[key], o2[key])) return false;
  936. keySet[key] = true;
  937. }
  938. for (key in o2) {
  939. if (!(key in keySet) &&
  940. key.charAt(0) !== '$' &&
  941. isDefined(o2[key]) &&
  942. !isFunction(o2[key])) return false;
  943. }
  944. return true;
  945. }
  946. }
  947. }
  948. return false;
  949. }
  950. var csp = function() {
  951. if (!isDefined(csp.rules)) {
  952. var ngCspElement = (document.querySelector('[ng-csp]') ||
  953. document.querySelector('[data-ng-csp]'));
  954. if (ngCspElement) {
  955. var ngCspAttribute = ngCspElement.getAttribute('ng-csp') ||
  956. ngCspElement.getAttribute('data-ng-csp');
  957. csp.rules = {
  958. noUnsafeEval: !ngCspAttribute || (ngCspAttribute.indexOf('no-unsafe-eval') !== -1),
  959. noInlineStyle: !ngCspAttribute || (ngCspAttribute.indexOf('no-inline-style') !== -1)
  960. };
  961. } else {
  962. csp.rules = {
  963. noUnsafeEval: noUnsafeEval(),
  964. noInlineStyle: false
  965. };
  966. }
  967. }
  968. return csp.rules;
  969. function noUnsafeEval() {
  970. try {
  971. /* jshint -W031, -W054 */
  972. new Function('');
  973. /* jshint +W031, +W054 */
  974. return false;
  975. } catch (e) {
  976. return true;
  977. }
  978. }
  979. };
  980. /**
  981. * @ngdoc directive
  982. * @module ng
  983. * @name ngJq
  984. *
  985. * @element ANY
  986. * @param {string=} ngJq the name of the library available under `window`
  987. * to be used for angular.element
  988. * @description
  989. * Use this directive to force the angular.element library. This should be
  990. * used to force either jqLite by leaving ng-jq blank or setting the name of
  991. * the jquery variable under window (eg. jQuery).
  992. *
  993. * Since angular looks for this directive when it is loaded (doesn't wait for the
  994. * DOMContentLoaded event), it must be placed on an element that comes before the script
  995. * which loads angular. Also, only the first instance of `ng-jq` will be used and all
  996. * others ignored.
  997. *
  998. * @example
  999. * This example shows how to force jqLite using the `ngJq` directive to the `html` tag.
  1000. ```html
  1001. <!doctype html>
  1002. <html ng-app ng-jq>
  1003. ...
  1004. ...
  1005. </html>
  1006. ```
  1007. * @example
  1008. * This example shows how to use a jQuery based library of a different name.
  1009. * The library name must be available at the top most 'window'.
  1010. ```html
  1011. <!doctype html>
  1012. <html ng-app ng-jq="jQueryLib">
  1013. ...
  1014. ...
  1015. </html>
  1016. ```
  1017. */
  1018. var jq = function() {
  1019. if (isDefined(jq.name_)) return jq.name_;
  1020. var el;
  1021. var i, ii = ngAttrPrefixes.length, prefix, name;
  1022. for (i = 0; i < ii; ++i) {
  1023. prefix = ngAttrPrefixes[i];
  1024. if (el = document.querySelector('[' + prefix.replace(':', '\\:') + 'jq]')) {
  1025. name = el.getAttribute(prefix + 'jq');
  1026. break;
  1027. }
  1028. }
  1029. return (jq.name_ = name);
  1030. };
  1031. function concat(array1, array2, index) {
  1032. return array1.concat(slice.call(array2, index));
  1033. }
  1034. function sliceArgs(args, startIndex) {
  1035. return slice.call(args, startIndex || 0);
  1036. }
  1037. /* jshint -W101 */
  1038. /**
  1039. * @ngdoc function
  1040. * @name angular.bind
  1041. * @module ng
  1042. * @kind function
  1043. *
  1044. * @description
  1045. * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
  1046. * `fn`). You can supply optional `args` that are prebound to the function. This feature is also
  1047. * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
  1048. * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
  1049. *
  1050. * @param {Object} self Context which `fn` should be evaluated in.
  1051. * @param {function()} fn Function to be bound.
  1052. * @param {...*} args Optional arguments to be prebound to the `fn` function call.
  1053. * @returns {function()} Function that wraps the `fn` with all the specified bindings.
  1054. */
  1055. /* jshint +W101 */
  1056. function bind(self, fn) {
  1057. var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
  1058. if (isFunction(fn) && !(fn instanceof RegExp)) {
  1059. return curryArgs.length
  1060. ? function() {
  1061. return arguments.length
  1062. ? fn.apply(self, concat(curryArgs, arguments, 0))
  1063. : fn.apply(self, curryArgs);
  1064. }
  1065. : function() {
  1066. return arguments.length
  1067. ? fn.apply(self, arguments)
  1068. : fn.call(self);
  1069. };
  1070. } else {
  1071. // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
  1072. return fn;
  1073. }
  1074. }
  1075. function toJsonReplacer(key, value) {
  1076. var val = value;
  1077. if (typeof key === 'string' && key.charAt(0) === '$' && key.charAt(1) === '$') {
  1078. val = undefined;
  1079. } else if (isWindow(value)) {
  1080. val = '$WINDOW';
  1081. } else if (value && document === value) {
  1082. val = '$DOCUMENT';
  1083. } else if (isScope(value)) {
  1084. val = '$SCOPE';
  1085. }
  1086. return val;
  1087. }
  1088. /**
  1089. * @ngdoc function
  1090. * @name angular.toJson
  1091. * @module ng
  1092. * @kind function
  1093. *
  1094. * @description
  1095. * Serializes input into a JSON-formatted string. Properties with leading $$ characters will be
  1096. * stripped since angular uses this notation internally.
  1097. *
  1098. * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
  1099. * @param {boolean|number} [pretty=2] If set to true, the JSON output will contain newlines and whitespace.
  1100. * If set to an integer, the JSON output will contain that many spaces per indentation.
  1101. * @returns {string|undefined} JSON-ified string representing `obj`.
  1102. */
  1103. function toJson(obj, pretty) {
  1104. if (typeof obj === 'undefined') return undefined;
  1105. if (!isNumber(pretty)) {
  1106. pretty = pretty ? 2 : null;
  1107. }
  1108. return JSON.stringify(obj, toJsonReplacer, pretty);
  1109. }
  1110. /**
  1111. * @ngdoc function
  1112. * @name angular.fromJson
  1113. * @module ng
  1114. * @kind function
  1115. *
  1116. * @description
  1117. * Deserializes a JSON string.
  1118. *
  1119. * @param {string} json JSON string to deserialize.
  1120. * @returns {Object|Array|string|number} Deserialized JSON string.
  1121. */
  1122. function fromJson(json) {
  1123. return isString(json)
  1124. ? JSON.parse(json)
  1125. : json;
  1126. }
  1127. function timezoneToOffset(timezone, fallback) {
  1128. var requestedTimezoneOffset = Date.parse('Jan 01, 1970 00:00:00 ' + timezone) / 60000;
  1129. return isNaN(requestedTimezoneOffset) ? fallback : requestedTimezoneOffset;
  1130. }
  1131. function addDateMinutes(date, minutes) {
  1132. date = new Date(date.getTime());
  1133. date.setMinutes(date.getMinutes() + minutes);
  1134. return date;
  1135. }
  1136. function convertTimezoneToLocal(date, timezone, reverse) {
  1137. reverse = reverse ? -1 : 1;
  1138. var timezoneOffset = timezoneToOffset(timezone, date.getTimezoneOffset());
  1139. return addDateMinutes(date, reverse * (timezoneOffset - date.getTimezoneOffset()));
  1140. }
  1141. /**
  1142. * @returns {string} Returns the string representation of the element.
  1143. */
  1144. function startingTag(element) {
  1145. element = jqLite(element).clone();
  1146. try {
  1147. // turns out IE does not let you set .html() on elements which
  1148. // are not allowed to have children. So we just ignore it.
  1149. element.empty();
  1150. } catch (e) {}
  1151. var elemHtml = jqLite('<div>').append(element).html();
  1152. try {
  1153. return element[0].nodeType === NODE_TYPE_TEXT ? lowercase(elemHtml) :
  1154. elemHtml.
  1155. match(/^(<[^>]+>)/)[1].
  1156. replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
  1157. } catch (e) {
  1158. return lowercase(elemHtml);
  1159. }
  1160. }
  1161. /////////////////////////////////////////////////
  1162. /**
  1163. * Tries to decode the URI component without throwing an exception.
  1164. *
  1165. * @private
  1166. * @param str value potential URI component to check.
  1167. * @returns {boolean} True if `value` can be decoded
  1168. * with the decodeURIComponent function.
  1169. */
  1170. function tryDecodeURIComponent(value) {
  1171. try {
  1172. return decodeURIComponent(value);
  1173. } catch (e) {
  1174. // Ignore any invalid uri component
  1175. }
  1176. }
  1177. /**
  1178. * Parses an escaped url query string into key-value pairs.
  1179. * @returns {Object.<string,boolean|Array>}
  1180. */
  1181. function parseKeyValue(/**string*/keyValue) {
  1182. var obj = {};
  1183. forEach((keyValue || "").split('&'), function(keyValue) {
  1184. var splitPoint, key, val;
  1185. if (keyValue) {
  1186. key = keyValue = keyValue.replace(/\+/g,'%20');
  1187. splitPoint = keyValue.indexOf('=');
  1188. if (splitPoint !== -1) {
  1189. key = keyValue.substring(0, splitPoint);
  1190. val = keyValue.substring(splitPoint + 1);
  1191. }
  1192. key = tryDecodeURIComponent(key);
  1193. if (isDefined(key)) {
  1194. val = isDefined(val) ? tryDecodeURIComponent(val) : true;
  1195. if (!hasOwnProperty.call(obj, key)) {
  1196. obj[key] = val;
  1197. } else if (isArray(obj[key])) {
  1198. obj[key].push(val);
  1199. } else {
  1200. obj[key] = [obj[key],val];
  1201. }
  1202. }
  1203. }
  1204. });
  1205. return obj;
  1206. }
  1207. function toKeyValue(obj) {
  1208. var parts = [];
  1209. forEach(obj, function(value, key) {
  1210. if (isArray(value)) {
  1211. forEach(value, function(arrayValue) {
  1212. parts.push(encodeUriQuery(key, true) +
  1213. (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
  1214. });
  1215. } else {
  1216. parts.push(encodeUriQuery(key, true) +
  1217. (value === true ? '' : '=' + encodeUriQuery(value, true)));
  1218. }
  1219. });
  1220. return parts.length ? parts.join('&') : '';
  1221. }
  1222. /**
  1223. * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
  1224. * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
  1225. * segments:
  1226. * segment = *pchar
  1227. * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  1228. * pct-encoded = "%" HEXDIG HEXDIG
  1229. * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  1230. * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
  1231. * / "*" / "+" / "," / ";" / "="
  1232. */
  1233. function encodeUriSegment(val) {
  1234. return encodeUriQuery(val, true).
  1235. replace(/%26/gi, '&').
  1236. replace(/%3D/gi, '=').
  1237. replace(/%2B/gi, '+');
  1238. }
  1239. /**
  1240. * This method is intended for encoding *key* or *value* parts of query component. We need a custom
  1241. * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
  1242. * encoded per http://tools.ietf.org/html/rfc3986:
  1243. * query = *( pchar / "/" / "?" )
  1244. * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  1245. * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  1246. * pct-encoded = "%" HEXDIG HEXDIG
  1247. * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
  1248. * / "*" / "+" / "," / ";" / "="
  1249. */
  1250. function encodeUriQuery(val, pctEncodeSpaces) {
  1251. return encodeURIComponent(val).
  1252. replace(/%40/gi, '@').
  1253. replace(/%3A/gi, ':').
  1254. replace(/%24/g, '$').
  1255. replace(/%2C/gi, ',').
  1256. replace(/%3B/gi, ';').
  1257. replace(/%20/g, (pctEncodeSpaces ? '%20' : '+'));
  1258. }
  1259. var ngAttrPrefixes = ['ng-', 'data-ng-', 'ng:', 'x-ng-'];
  1260. function getNgAttribute(element, ngAttr) {
  1261. var attr, i, ii = ngAttrPrefixes.length;
  1262. for (i = 0; i < ii; ++i) {
  1263. attr = ngAttrPrefixes[i] + ngAttr;
  1264. if (isString(attr = element.getAttribute(attr))) {
  1265. return attr;
  1266. }
  1267. }
  1268. return null;
  1269. }
  1270. /**
  1271. * @ngdoc directive
  1272. * @name ngApp
  1273. * @module ng
  1274. *
  1275. * @element ANY
  1276. * @param {angular.Module} ngApp an optional application
  1277. * {@link angular.module module} name to load.
  1278. * @param {boolean=} ngStrictDi if this attribute is present on the app element, the injector will be
  1279. * created in "strict-di" mode. This means that the application will fail to invoke functions which
  1280. * do not use explicit function annotation (and are thus unsuitable for minification), as described
  1281. * in {@link guide/di the Dependency Injection guide}, and useful debugging info will assist in
  1282. * tracking down the root of these bugs.
  1283. *
  1284. * @description
  1285. *
  1286. * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
  1287. * designates the **root element** of the application and is typically placed near the root element
  1288. * of the page - e.g. on the `<body>` or `<html>` tags.
  1289. *
  1290. * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
  1291. * found in the document will be used to define the root element to auto-bootstrap as an
  1292. * application. To run multiple applications in an HTML document you must manually bootstrap them using
  1293. * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
  1294. *
  1295. * You can specify an **AngularJS module** to be used as the root module for the application. This
  1296. * module will be loaded into the {@link auto.$injector} when the application is bootstrapped. It
  1297. * should contain the application code needed or have dependencies on other modules that will
  1298. * contain the code. See {@link angular.module} for more information.
  1299. *
  1300. * In the example below if the `ngApp` directive were not placed on the `html` element then the
  1301. * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
  1302. * would not be resolved to `3`.
  1303. *
  1304. * `ngApp` is the easiest, and most common way to bootstrap an application.
  1305. *
  1306. <example module="ngAppDemo">
  1307. <file name="index.html">
  1308. <div ng-controller="ngAppDemoController">
  1309. I can add: {{a}} + {{b}} = {{ a+b }}
  1310. </div>
  1311. </file>
  1312. <file name="script.js">
  1313. angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
  1314. $scope.a = 1;
  1315. $scope.b = 2;
  1316. });
  1317. </file>
  1318. </example>
  1319. *
  1320. * Using `ngStrictDi`, you would see something like this:
  1321. *
  1322. <example ng-app-included="true">
  1323. <file name="index.html">
  1324. <div ng-app="ngAppStrictDemo" ng-strict-di>
  1325. <div ng-controller="GoodController1">
  1326. I can add: {{a}} + {{b}} = {{ a+b }}
  1327. <p>This renders because the controller does not fail to
  1328. instantiate, by using explicit annotation style (see
  1329. script.js for details)
  1330. </p>
  1331. </div>
  1332. <div ng-controller="GoodController2">
  1333. Name: <input ng-model="name"><br />
  1334. Hello, {{name}}!
  1335. <p>This renders because the controller does not fail to
  1336. instantiate, by using explicit annotation style
  1337. (see script.js for details)
  1338. </p>
  1339. </div>
  1340. <div ng-controller="BadController">
  1341. I can add: {{a}} + {{b}} = {{ a+b }}
  1342. <p>The controller could not be instantiated, due to relying
  1343. on automatic function annotations (which are disabled in
  1344. strict mode). As such, the content of this section is not
  1345. interpolated, and there should be an error in your web console.
  1346. </p>
  1347. </div>
  1348. </div>
  1349. </file>
  1350. <file name="script.js">
  1351. angular.module('ngAppStrictDemo', [])
  1352. // BadController will fail to instantiate, due to relying on automatic function annotation,
  1353. // rather than an explicit annotation
  1354. .controller('BadController', function($scope) {
  1355. $scope.a = 1;
  1356. $scope.b = 2;
  1357. })
  1358. // Unlike BadController, GoodController1 and GoodController2 will not fail to be instantiated,
  1359. // due to using explicit annotations using the array style and $inject property, respectively.
  1360. .controller('GoodController1', ['$scope', function($scope) {
  1361. $scope.a = 1;
  1362. $scope.b = 2;
  1363. }])
  1364. .controller('GoodController2', GoodController2);
  1365. function GoodController2($scope) {
  1366. $scope.name = "World";
  1367. }
  1368. GoodController2.$inject = ['$scope'];
  1369. </file>
  1370. <file name="style.css">
  1371. div[ng-controller] {
  1372. margin-bottom: 1em;
  1373. -webkit-border-radius: 4px;
  1374. border-radius: 4px;
  1375. border: 1px solid;
  1376. padding: .5em;
  1377. }
  1378. div[ng-controller^=Good] {
  1379. border-color: #d6e9c6;
  1380. background-color: #dff0d8;
  1381. color: #3c763d;
  1382. }
  1383. div[ng-controller^=Bad] {
  1384. border-color: #ebccd1;
  1385. background-color: #f2dede;
  1386. color: #a94442;
  1387. margin-bottom: 0;
  1388. }
  1389. </file>
  1390. </example>
  1391. */
  1392. function angularInit(element, bootstrap) {
  1393. var appElement,
  1394. module,
  1395. config = {};
  1396. // The element `element` has priority over any other element
  1397. forEach(ngAttrPrefixes, function(prefix) {
  1398. var name = prefix + 'app';
  1399. if (!appElement && element.hasAttribute && element.hasAttribute(name)) {
  1400. appElement = element;
  1401. module = element.getAttribute(name);
  1402. }
  1403. });
  1404. forEach(ngAttrPrefixes, function(prefix) {
  1405. var name = prefix + 'app';
  1406. var candidate;
  1407. if (!appElement && (candidate = element.querySelector('[' + name.replace(':', '\\:') + ']'))) {
  1408. appElement = candidate;
  1409. module = candidate.getAttribute(name);
  1410. }
  1411. });
  1412. if (appElement) {
  1413. config.strictDi = getNgAttribute(appElement, "strict-di") !== null;
  1414. bootstrap(appElement, module ? [module] : [], config);
  1415. }
  1416. }
  1417. /**
  1418. * @ngdoc function
  1419. * @name angular.bootstrap
  1420. * @module ng
  1421. * @description
  1422. * Use this function to manually start up angular application.
  1423. *
  1424. * See: {@link guide/bootstrap Bootstrap}
  1425. *
  1426. * Note that Protractor based end-to-end tests cannot use this function to bootstrap manually.
  1427. * They must use {@link ng.directive:ngApp ngApp}.
  1428. *
  1429. * Angular will detect if it has been loaded into the browser more than once and only allow the
  1430. * first loaded script to be bootstrapped and will report a warning to the browser console for
  1431. * each of the subsequent scripts. This prevents strange results in applications, where otherwise
  1432. * multiple instances of Angular try to work on the DOM.
  1433. *
  1434. * ```html
  1435. * <!doctype html>
  1436. * <html>
  1437. * <body>
  1438. * <div ng-controller="WelcomeController">
  1439. * {{greeting}}
  1440. * </div>
  1441. *
  1442. * <script src="angular.js"></script>
  1443. * <script>
  1444. * var app = angular.module('demo', [])
  1445. * .controller('WelcomeController', function($scope) {
  1446. * $scope.greeting = 'Welcome!';
  1447. * });
  1448. * angular.bootstrap(document, ['demo']);
  1449. * </script>
  1450. * </body>
  1451. * </html>
  1452. * ```
  1453. *
  1454. * @param {DOMElement} element DOM element which is the root of angular application.
  1455. * @param {Array<String|Function|Array>=} modules an array of modules to load into the application.
  1456. * Each item in the array should be the name of a predefined module or a (DI annotated)
  1457. * function that will be invoked by the injector as a `config` block.
  1458. * See: {@link angular.module modules}
  1459. * @param {Object=} config an object for defining configuration options for the application. The
  1460. * following keys are supported:
  1461. *
  1462. * * `strictDi` - disable automatic function annotation for the application. This is meant to
  1463. * assist in finding bugs which break minified code. Defaults to `false`.
  1464. *
  1465. * @returns {auto.$injector} Returns the newly created injector for this app.
  1466. */
  1467. function bootstrap(element, modules, config) {
  1468. if (!isObject(config)) config = {};
  1469. var defaultConfig = {
  1470. strictDi: false
  1471. };
  1472. config = extend(defaultConfig, config);
  1473. var doBootstrap = function() {
  1474. element = jqLite(element);
  1475. if (element.injector()) {
  1476. var tag = (element[0] === document) ? 'document' : startingTag(element);
  1477. //Encode angle brackets to prevent input from being sanitized to empty string #8683
  1478. throw ngMinErr(
  1479. 'btstrpd',
  1480. "App Already Bootstrapped with this Element '{0}'",
  1481. tag.replace(/</,'&lt;').replace(/>/,'&gt;'));
  1482. }
  1483. modules = modules || [];
  1484. modules.unshift(['$provide', function($provide) {
  1485. $provide.value('$rootElement', element);
  1486. }]);
  1487. if (config.debugInfoEnabled) {
  1488. // Pushing so that this overrides `debugInfoEnabled` setting defined in user's `modules`.
  1489. modules.push(['$compileProvider', function($compileProvider) {
  1490. $compileProvider.debugInfoEnabled(true);
  1491. }]);
  1492. }
  1493. modules.unshift('ng');
  1494. var injector = createInjector(modules, config.strictDi);
  1495. injector.invoke(['$rootScope', '$rootElement', '$compile', '$injector',
  1496. function bootstrapApply(scope, element, compile, injector) {
  1497. scope.$apply(function() {
  1498. element.data('$injector', injector);
  1499. compile(element)(scope);
  1500. });
  1501. }]
  1502. );
  1503. return injector;
  1504. };
  1505. var NG_ENABLE_DEBUG_INFO = /^NG_ENABLE_DEBUG_INFO!/;
  1506. var NG_DEFER_BOOTSTRAP = /^NG_DEFER_BOOTSTRAP!/;
  1507. if (window && NG_ENABLE_DEBUG_INFO.test(window.name)) {
  1508. config.debugInfoEnabled = true;
  1509. window.name = window.name.replace(NG_ENABLE_DEBUG_INFO, '');
  1510. }
  1511. if (window && !NG_DEFER_