PageRenderTime 342ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/files/angularjs/1.1.2/angular.js

https://gitlab.com/Mirros/jsdelivr
JavaScript | 1618 lines | 778 code | 167 blank | 673 comment | 210 complexity | c454c222eeee5e45365aefecec529561 MD5 | raw file
  1. /**
  2. * @license AngularJS v1.1.2
  3. * (c) 2010-2012 Google, Inc. http://angularjs.org
  4. * License: MIT
  5. */
  6. (function(window, document, undefined) {
  7. 'use strict';
  8. ////////////////////////////////////
  9. /**
  10. * @ngdoc function
  11. * @name angular.lowercase
  12. * @function
  13. *
  14. * @description Converts the specified string to lowercase.
  15. * @param {string} string String to be converted to lowercase.
  16. * @returns {string} Lowercased string.
  17. */
  18. var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
  19. /**
  20. * @ngdoc function
  21. * @name angular.uppercase
  22. * @function
  23. *
  24. * @description Converts the specified string to uppercase.
  25. * @param {string} string String to be converted to uppercase.
  26. * @returns {string} Uppercased string.
  27. */
  28. var uppercase = function(string){return isString(string) ? string.toUpperCase() : string;};
  29. var manualLowercase = function(s) {
  30. return isString(s)
  31. ? s.replace(/[A-Z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) | 32);})
  32. : s;
  33. };
  34. var manualUppercase = function(s) {
  35. return isString(s)
  36. ? s.replace(/[a-z]/g, function(ch) {return fromCharCode(ch.charCodeAt(0) & ~32);})
  37. : s;
  38. };
  39. // String#toLowerCase and String#toUpperCase don't produce correct results in browsers with Turkish
  40. // locale, for this reason we need to detect this case and redefine lowercase/uppercase methods
  41. // with correct but slower alternatives.
  42. if ('i' !== 'I'.toLowerCase()) {
  43. lowercase = manualLowercase;
  44. uppercase = manualUppercase;
  45. }
  46. function fromCharCode(code) {return String.fromCharCode(code);}
  47. var Error = window.Error,
  48. /** holds major version number for IE or NaN for real browsers */
  49. msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
  50. jqLite, // delay binding since jQuery could be loaded after us.
  51. jQuery, // delay binding
  52. slice = [].slice,
  53. push = [].push,
  54. toString = Object.prototype.toString,
  55. /** @name angular */
  56. angular = window.angular || (window.angular = {}),
  57. angularModule,
  58. nodeName_,
  59. uid = ['0', '0', '0'];
  60. /**
  61. * @ngdoc function
  62. * @name angular.forEach
  63. * @function
  64. *
  65. * @description
  66. * Invokes the `iterator` function once for each item in `obj` collection, which can be either an
  67. * object or an array. The `iterator` function is invoked with `iterator(value, key)`, where `value`
  68. * is the value of an object property or an array element and `key` is the object property key or
  69. * array element index. Specifying a `context` for the function is optional.
  70. *
  71. * Note: this function was previously known as `angular.foreach`.
  72. *
  73. <pre>
  74. var values = {name: 'misko', gender: 'male'};
  75. var log = [];
  76. angular.forEach(values, function(value, key){
  77. this.push(key + ': ' + value);
  78. }, log);
  79. expect(log).toEqual(['name: misko', 'gender:male']);
  80. </pre>
  81. *
  82. * @param {Object|Array} obj Object to iterate over.
  83. * @param {Function} iterator Iterator function.
  84. * @param {Object=} context Object to become context (`this`) for the iterator function.
  85. * @returns {Object|Array} Reference to `obj`.
  86. */
  87. function forEach(obj, iterator, context) {
  88. var key;
  89. if (obj) {
  90. if (isFunction(obj)){
  91. for (key in obj) {
  92. if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
  93. iterator.call(context, obj[key], key);
  94. }
  95. }
  96. } else if (obj.forEach && obj.forEach !== forEach) {
  97. obj.forEach(iterator, context);
  98. } else if (isObject(obj) && isNumber(obj.length)) {
  99. for (key = 0; key < obj.length; key++)
  100. iterator.call(context, obj[key], key);
  101. } else {
  102. for (key in obj) {
  103. if (obj.hasOwnProperty(key)) {
  104. iterator.call(context, obj[key], key);
  105. }
  106. }
  107. }
  108. }
  109. return obj;
  110. }
  111. function sortedKeys(obj) {
  112. var keys = [];
  113. for (var key in obj) {
  114. if (obj.hasOwnProperty(key)) {
  115. keys.push(key);
  116. }
  117. }
  118. return keys.sort();
  119. }
  120. function forEachSorted(obj, iterator, context) {
  121. var keys = sortedKeys(obj);
  122. for ( var i = 0; i < keys.length; i++) {
  123. iterator.call(context, obj[keys[i]], keys[i]);
  124. }
  125. return keys;
  126. }
  127. /**
  128. * when using forEach the params are value, key, but it is often useful to have key, value.
  129. * @param {function(string, *)} iteratorFn
  130. * @returns {function(*, string)}
  131. */
  132. function reverseParams(iteratorFn) {
  133. return function(value, key) { iteratorFn(key, value) };
  134. }
  135. /**
  136. * A consistent way of creating unique IDs in angular. The ID is a sequence of alpha numeric
  137. * characters such as '012ABC'. The reason why we are not using simply a number counter is that
  138. * the number string gets longer over time, and it can also overflow, where as the the nextId
  139. * will grow much slower, it is a string, and it will never overflow.
  140. *
  141. * @returns an unique alpha-numeric string
  142. */
  143. function nextUid() {
  144. var index = uid.length;
  145. var digit;
  146. while(index) {
  147. index--;
  148. digit = uid[index].charCodeAt(0);
  149. if (digit == 57 /*'9'*/) {
  150. uid[index] = 'A';
  151. return uid.join('');
  152. }
  153. if (digit == 90 /*'Z'*/) {
  154. uid[index] = '0';
  155. } else {
  156. uid[index] = String.fromCharCode(digit + 1);
  157. return uid.join('');
  158. }
  159. }
  160. uid.unshift('0');
  161. return uid.join('');
  162. }
  163. /**
  164. * @ngdoc function
  165. * @name angular.extend
  166. * @function
  167. *
  168. * @description
  169. * Extends the destination object `dst` by copying all of the properties from the `src` object(s)
  170. * to `dst`. You can specify multiple `src` objects.
  171. *
  172. * @param {Object} dst Destination object.
  173. * @param {...Object} src Source object(s).
  174. */
  175. function extend(dst) {
  176. forEach(arguments, function(obj){
  177. if (obj !== dst) {
  178. forEach(obj, function(value, key){
  179. dst[key] = value;
  180. });
  181. }
  182. });
  183. return dst;
  184. }
  185. function int(str) {
  186. return parseInt(str, 10);
  187. }
  188. function inherit(parent, extra) {
  189. return extend(new (extend(function() {}, {prototype:parent}))(), extra);
  190. }
  191. /**
  192. * @ngdoc function
  193. * @name angular.noop
  194. * @function
  195. *
  196. * @description
  197. * A function that performs no operations. This function can be useful when writing code in the
  198. * functional style.
  199. <pre>
  200. function foo(callback) {
  201. var result = calculateResult();
  202. (callback || angular.noop)(result);
  203. }
  204. </pre>
  205. */
  206. function noop() {}
  207. noop.$inject = [];
  208. /**
  209. * @ngdoc function
  210. * @name angular.identity
  211. * @function
  212. *
  213. * @description
  214. * A function that returns its first argument. This function is useful when writing code in the
  215. * functional style.
  216. *
  217. <pre>
  218. function transformer(transformationFn, value) {
  219. return (transformationFn || identity)(value);
  220. };
  221. </pre>
  222. */
  223. function identity($) {return $;}
  224. identity.$inject = [];
  225. function valueFn(value) {return function() {return value;};}
  226. /**
  227. * @ngdoc function
  228. * @name angular.isUndefined
  229. * @function
  230. *
  231. * @description
  232. * Determines if a reference is undefined.
  233. *
  234. * @param {*} value Reference to check.
  235. * @returns {boolean} True if `value` is undefined.
  236. */
  237. function isUndefined(value){return typeof value == 'undefined';}
  238. /**
  239. * @ngdoc function
  240. * @name angular.isDefined
  241. * @function
  242. *
  243. * @description
  244. * Determines if a reference is defined.
  245. *
  246. * @param {*} value Reference to check.
  247. * @returns {boolean} True if `value` is defined.
  248. */
  249. function isDefined(value){return typeof value != 'undefined';}
  250. /**
  251. * @ngdoc function
  252. * @name angular.isObject
  253. * @function
  254. *
  255. * @description
  256. * Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
  257. * considered to be objects.
  258. *
  259. * @param {*} value Reference to check.
  260. * @returns {boolean} True if `value` is an `Object` but not `null`.
  261. */
  262. function isObject(value){return value != null && typeof value == 'object';}
  263. /**
  264. * @ngdoc function
  265. * @name angular.isString
  266. * @function
  267. *
  268. * @description
  269. * Determines if a reference is a `String`.
  270. *
  271. * @param {*} value Reference to check.
  272. * @returns {boolean} True if `value` is a `String`.
  273. */
  274. function isString(value){return typeof value == 'string';}
  275. /**
  276. * @ngdoc function
  277. * @name angular.isNumber
  278. * @function
  279. *
  280. * @description
  281. * Determines if a reference is a `Number`.
  282. *
  283. * @param {*} value Reference to check.
  284. * @returns {boolean} True if `value` is a `Number`.
  285. */
  286. function isNumber(value){return typeof value == 'number';}
  287. /**
  288. * @ngdoc function
  289. * @name angular.isDate
  290. * @function
  291. *
  292. * @description
  293. * Determines if a value is a date.
  294. *
  295. * @param {*} value Reference to check.
  296. * @returns {boolean} True if `value` is a `Date`.
  297. */
  298. function isDate(value){
  299. return toString.apply(value) == '[object Date]';
  300. }
  301. /**
  302. * @ngdoc function
  303. * @name angular.isArray
  304. * @function
  305. *
  306. * @description
  307. * Determines if a reference is an `Array`.
  308. *
  309. * @param {*} value Reference to check.
  310. * @returns {boolean} True if `value` is an `Array`.
  311. */
  312. function isArray(value) {
  313. return toString.apply(value) == '[object Array]';
  314. }
  315. /**
  316. * @ngdoc function
  317. * @name angular.isFunction
  318. * @function
  319. *
  320. * @description
  321. * Determines if a reference is a `Function`.
  322. *
  323. * @param {*} value Reference to check.
  324. * @returns {boolean} True if `value` is a `Function`.
  325. */
  326. function isFunction(value){return typeof value == 'function';}
  327. /**
  328. * Checks if `obj` is a window object.
  329. *
  330. * @private
  331. * @param {*} obj Object to check
  332. * @returns {boolean} True if `obj` is a window obj.
  333. */
  334. function isWindow(obj) {
  335. return obj && obj.document && obj.location && obj.alert && obj.setInterval;
  336. }
  337. function isScope(obj) {
  338. return obj && obj.$evalAsync && obj.$watch;
  339. }
  340. function isFile(obj) {
  341. return toString.apply(obj) === '[object File]';
  342. }
  343. function isBoolean(value) {
  344. return typeof value == 'boolean';
  345. }
  346. function trim(value) {
  347. return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
  348. }
  349. /**
  350. * @ngdoc function
  351. * @name angular.isElement
  352. * @function
  353. *
  354. * @description
  355. * Determines if a reference is a DOM element (or wrapped jQuery element).
  356. *
  357. * @param {*} value Reference to check.
  358. * @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
  359. */
  360. function isElement(node) {
  361. return node &&
  362. (node.nodeName // we are a direct element
  363. || (node.bind && node.find)); // we have a bind and find method part of jQuery API
  364. }
  365. /**
  366. * @param str 'key1,key2,...'
  367. * @returns {object} in the form of {key1:true, key2:true, ...}
  368. */
  369. function makeMap(str){
  370. var obj = {}, items = str.split(","), i;
  371. for ( i = 0; i < items.length; i++ )
  372. obj[ items[i] ] = true;
  373. return obj;
  374. }
  375. if (msie < 9) {
  376. nodeName_ = function(element) {
  377. element = element.nodeName ? element : element[0];
  378. return (element.scopeName && element.scopeName != 'HTML')
  379. ? uppercase(element.scopeName + ':' + element.nodeName) : element.nodeName;
  380. };
  381. } else {
  382. nodeName_ = function(element) {
  383. return element.nodeName ? element.nodeName : element[0].nodeName;
  384. };
  385. }
  386. function map(obj, iterator, context) {
  387. var results = [];
  388. forEach(obj, function(value, index, list) {
  389. results.push(iterator.call(context, value, index, list));
  390. });
  391. return results;
  392. }
  393. /**
  394. * @description
  395. * Determines the number of elements in an array, the number of properties an object has, or
  396. * the length of a string.
  397. *
  398. * Note: This function is used to augment the Object type in Angular expressions. See
  399. * {@link angular.Object} for more information about Angular arrays.
  400. *
  401. * @param {Object|Array|string} obj Object, array, or string to inspect.
  402. * @param {boolean} [ownPropsOnly=false] Count only "own" properties in an object
  403. * @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array.
  404. */
  405. function size(obj, ownPropsOnly) {
  406. var size = 0, key;
  407. if (isArray(obj) || isString(obj)) {
  408. return obj.length;
  409. } else if (isObject(obj)){
  410. for (key in obj)
  411. if (!ownPropsOnly || obj.hasOwnProperty(key))
  412. size++;
  413. }
  414. return size;
  415. }
  416. function includes(array, obj) {
  417. return indexOf(array, obj) != -1;
  418. }
  419. function indexOf(array, obj) {
  420. if (array.indexOf) return array.indexOf(obj);
  421. for ( var i = 0; i < array.length; i++) {
  422. if (obj === array[i]) return i;
  423. }
  424. return -1;
  425. }
  426. function arrayRemove(array, value) {
  427. var index = indexOf(array, value);
  428. if (index >=0)
  429. array.splice(index, 1);
  430. return value;
  431. }
  432. function isLeafNode (node) {
  433. if (node) {
  434. switch (node.nodeName) {
  435. case "OPTION":
  436. case "PRE":
  437. case "TITLE":
  438. return true;
  439. }
  440. }
  441. return false;
  442. }
  443. /**
  444. * @ngdoc function
  445. * @name angular.copy
  446. * @function
  447. *
  448. * @description
  449. * Creates a deep copy of `source`, which should be an object or an array.
  450. *
  451. * * If no destination is supplied, a copy of the object or array is created.
  452. * * If a destination is provided, all of its elements (for array) or properties (for objects)
  453. * are deleted and then all elements/properties from the source are copied to it.
  454. * * If `source` is not an object or array, `source` is returned.
  455. *
  456. * Note: this function is used to augment the Object type in Angular expressions. See
  457. * {@link ng.$filter} for more information about Angular arrays.
  458. *
  459. * @param {*} source The source that will be used to make a copy.
  460. * Can be any type, including primitives, `null`, and `undefined`.
  461. * @param {(Object|Array)=} destination Destination into which the source is copied. If
  462. * provided, must be of the same type as `source`.
  463. * @returns {*} The copy or updated `destination`, if `destination` was specified.
  464. */
  465. function copy(source, destination){
  466. if (isWindow(source) || isScope(source)) throw Error("Can't copy Window or Scope");
  467. if (!destination) {
  468. destination = source;
  469. if (source) {
  470. if (isArray(source)) {
  471. destination = copy(source, []);
  472. } else if (isDate(source)) {
  473. destination = new Date(source.getTime());
  474. } else if (isObject(source)) {
  475. destination = copy(source, {});
  476. }
  477. }
  478. } else {
  479. if (source === destination) throw Error("Can't copy equivalent objects or arrays");
  480. if (isArray(source)) {
  481. while(destination.length) {
  482. destination.pop();
  483. }
  484. for ( var i = 0; i < source.length; i++) {
  485. destination.push(copy(source[i]));
  486. }
  487. } else {
  488. forEach(destination, function(value, key){
  489. delete destination[key];
  490. });
  491. for ( var key in source) {
  492. destination[key] = copy(source[key]);
  493. }
  494. }
  495. }
  496. return destination;
  497. }
  498. /**
  499. * Create a shallow copy of an object
  500. */
  501. function shallowCopy(src, dst) {
  502. dst = dst || {};
  503. for(var key in src) {
  504. if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
  505. dst[key] = src[key];
  506. }
  507. }
  508. return dst;
  509. }
  510. /**
  511. * @ngdoc function
  512. * @name angular.equals
  513. * @function
  514. *
  515. * @description
  516. * Determines if two objects or two values are equivalent. Supports value types, arrays and
  517. * objects.
  518. *
  519. * Two objects or values are considered equivalent if at least one of the following is true:
  520. *
  521. * * Both objects or values pass `===` comparison.
  522. * * Both objects or values are of the same type and all of their properties pass `===` comparison.
  523. * * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
  524. *
  525. * During a property comparision, properties of `function` type and properties with names
  526. * that begin with `$` are ignored.
  527. *
  528. * Scope and DOMWindow objects are being compared only be identify (`===`).
  529. *
  530. * @param {*} o1 Object or value to compare.
  531. * @param {*} o2 Object or value to compare.
  532. * @returns {boolean} True if arguments are equal.
  533. */
  534. function equals(o1, o2) {
  535. if (o1 === o2) return true;
  536. if (o1 === null || o2 === null) return false;
  537. if (o1 !== o1 && o2 !== o2) return true; // NaN === NaN
  538. var t1 = typeof o1, t2 = typeof o2, length, key, keySet;
  539. if (t1 == t2) {
  540. if (t1 == 'object') {
  541. if (isArray(o1)) {
  542. if ((length = o1.length) == o2.length) {
  543. for(key=0; key<length; key++) {
  544. if (!equals(o1[key], o2[key])) return false;
  545. }
  546. return true;
  547. }
  548. } else if (isDate(o1)) {
  549. return isDate(o2) && o1.getTime() == o2.getTime();
  550. } else {
  551. if (isScope(o1) || isScope(o2) || isWindow(o1) || isWindow(o2)) return false;
  552. keySet = {};
  553. for(key in o1) {
  554. if (key.charAt(0) === '$' || isFunction(o1[key])) continue;
  555. if (!equals(o1[key], o2[key])) return false;
  556. keySet[key] = true;
  557. }
  558. for(key in o2) {
  559. if (!keySet[key] &&
  560. key.charAt(0) !== '$' &&
  561. o2[key] !== undefined &&
  562. !isFunction(o2[key])) return false;
  563. }
  564. return true;
  565. }
  566. }
  567. }
  568. return false;
  569. }
  570. function concat(array1, array2, index) {
  571. return array1.concat(slice.call(array2, index));
  572. }
  573. function sliceArgs(args, startIndex) {
  574. return slice.call(args, startIndex || 0);
  575. }
  576. /**
  577. * @ngdoc function
  578. * @name angular.bind
  579. * @function
  580. *
  581. * @description
  582. * Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
  583. * `fn`). You can supply optional `args` that are are prebound to the function. This feature is also
  584. * known as [function currying](http://en.wikipedia.org/wiki/Currying).
  585. *
  586. * @param {Object} self Context which `fn` should be evaluated in.
  587. * @param {function()} fn Function to be bound.
  588. * @param {...*} args Optional arguments to be prebound to the `fn` function call.
  589. * @returns {function()} Function that wraps the `fn` with all the specified bindings.
  590. */
  591. function bind(self, fn) {
  592. var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
  593. if (isFunction(fn) && !(fn instanceof RegExp)) {
  594. return curryArgs.length
  595. ? function() {
  596. return arguments.length
  597. ? fn.apply(self, curryArgs.concat(slice.call(arguments, 0)))
  598. : fn.apply(self, curryArgs);
  599. }
  600. : function() {
  601. return arguments.length
  602. ? fn.apply(self, arguments)
  603. : fn.call(self);
  604. };
  605. } else {
  606. // in IE, native methods are not functions so they cannot be bound (note: they don't need to be)
  607. return fn;
  608. }
  609. }
  610. function toJsonReplacer(key, value) {
  611. var val = value;
  612. if (/^\$+/.test(key)) {
  613. val = undefined;
  614. } else if (isWindow(value)) {
  615. val = '$WINDOW';
  616. } else if (value && document === value) {
  617. val = '$DOCUMENT';
  618. } else if (isScope(value)) {
  619. val = '$SCOPE';
  620. }
  621. return val;
  622. }
  623. /**
  624. * @ngdoc function
  625. * @name angular.toJson
  626. * @function
  627. *
  628. * @description
  629. * Serializes input into a JSON-formatted string.
  630. *
  631. * @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
  632. * @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
  633. * @returns {string} Jsonified string representing `obj`.
  634. */
  635. function toJson(obj, pretty) {
  636. return JSON.stringify(obj, toJsonReplacer, pretty ? ' ' : null);
  637. }
  638. /**
  639. * @ngdoc function
  640. * @name angular.fromJson
  641. * @function
  642. *
  643. * @description
  644. * Deserializes a JSON string.
  645. *
  646. * @param {string} json JSON string to deserialize.
  647. * @returns {Object|Array|Date|string|number} Deserialized thingy.
  648. */
  649. function fromJson(json) {
  650. return isString(json)
  651. ? JSON.parse(json)
  652. : json;
  653. }
  654. function toBoolean(value) {
  655. if (value && value.length !== 0) {
  656. var v = lowercase("" + value);
  657. value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
  658. } else {
  659. value = false;
  660. }
  661. return value;
  662. }
  663. /**
  664. * @returns {string} Returns the string representation of the element.
  665. */
  666. function startingTag(element) {
  667. element = jqLite(element).clone();
  668. try {
  669. // turns out IE does not let you set .html() on elements which
  670. // are not allowed to have children. So we just ignore it.
  671. element.html('');
  672. } catch(e) {}
  673. return jqLite('<div>').append(element).html().
  674. match(/^(<[^>]+>)/)[1].
  675. replace(/^<([\w\-]+)/, function(match, nodeName) { return '<' + lowercase(nodeName); });
  676. }
  677. /////////////////////////////////////////////////
  678. /**
  679. * Parses an escaped url query string into key-value pairs.
  680. * @returns Object.<(string|boolean)>
  681. */
  682. function parseKeyValue(/**string*/keyValue) {
  683. var obj = {}, key_value, key;
  684. forEach((keyValue || "").split('&'), function(keyValue){
  685. if (keyValue) {
  686. key_value = keyValue.split('=');
  687. key = decodeURIComponent(key_value[0]);
  688. obj[key] = isDefined(key_value[1]) ? decodeURIComponent(key_value[1]) : true;
  689. }
  690. });
  691. return obj;
  692. }
  693. function toKeyValue(obj) {
  694. var parts = [];
  695. forEach(obj, function(value, key) {
  696. parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true)));
  697. });
  698. return parts.length ? parts.join('&') : '';
  699. }
  700. /**
  701. * We need our custom method because encodeURIComponent is too agressive and doesn't follow
  702. * http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
  703. * segments:
  704. * segment = *pchar
  705. * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  706. * pct-encoded = "%" HEXDIG HEXDIG
  707. * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  708. * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
  709. * / "*" / "+" / "," / ";" / "="
  710. */
  711. function encodeUriSegment(val) {
  712. return encodeUriQuery(val, true).
  713. replace(/%26/gi, '&').
  714. replace(/%3D/gi, '=').
  715. replace(/%2B/gi, '+');
  716. }
  717. /**
  718. * This method is intended for encoding *key* or *value* parts of query component. We need a custom
  719. * method becuase encodeURIComponent is too agressive and encodes stuff that doesn't have to be
  720. * encoded per http://tools.ietf.org/html/rfc3986:
  721. * query = *( pchar / "/" / "?" )
  722. * pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
  723. * unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
  724. * pct-encoded = "%" HEXDIG HEXDIG
  725. * sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
  726. * / "*" / "+" / "," / ";" / "="
  727. */
  728. function encodeUriQuery(val, pctEncodeSpaces) {
  729. return encodeURIComponent(val).
  730. replace(/%40/gi, '@').
  731. replace(/%3A/gi, ':').
  732. replace(/%24/g, '$').
  733. replace(/%2C/gi, ',').
  734. replace((pctEncodeSpaces ? null : /%20/g), '+');
  735. }
  736. /**
  737. * @ngdoc directive
  738. * @name ng.directive:ngApp
  739. *
  740. * @element ANY
  741. * @param {angular.Module} ngApp an optional application
  742. * {@link angular.module module} name to load.
  743. *
  744. * @description
  745. *
  746. * Use this directive to auto-bootstrap on application. Only
  747. * one directive can be used per HTML document. The directive
  748. * designates the root of the application and is typically placed
  749. * ot the root of the page.
  750. *
  751. * In the example below if the `ngApp` directive would not be placed
  752. * on the `html` element then the document would not be compiled
  753. * and the `{{ 1+2 }}` would not be resolved to `3`.
  754. *
  755. * `ngApp` is the easiest way to bootstrap an application.
  756. *
  757. <doc:example>
  758. <doc:source>
  759. I can add: 1 + 2 = {{ 1+2 }}
  760. </doc:source>
  761. </doc:example>
  762. *
  763. */
  764. function angularInit(element, bootstrap) {
  765. var elements = [element],
  766. appElement,
  767. module,
  768. names = ['ng:app', 'ng-app', 'x-ng-app', 'data-ng-app'],
  769. NG_APP_CLASS_REGEXP = /\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;
  770. function append(element) {
  771. element && elements.push(element);
  772. }
  773. forEach(names, function(name) {
  774. names[name] = true;
  775. append(document.getElementById(name));
  776. name = name.replace(':', '\\:');
  777. if (element.querySelectorAll) {
  778. forEach(element.querySelectorAll('.' + name), append);
  779. forEach(element.querySelectorAll('.' + name + '\\:'), append);
  780. forEach(element.querySelectorAll('[' + name + ']'), append);
  781. }
  782. });
  783. forEach(elements, function(element) {
  784. if (!appElement) {
  785. var className = ' ' + element.className + ' ';
  786. var match = NG_APP_CLASS_REGEXP.exec(className);
  787. if (match) {
  788. appElement = element;
  789. module = (match[2] || '').replace(/\s+/g, ',');
  790. } else {
  791. forEach(element.attributes, function(attr) {
  792. if (!appElement && names[attr.name]) {
  793. appElement = element;
  794. module = attr.value;
  795. }
  796. });
  797. }
  798. }
  799. });
  800. if (appElement) {
  801. bootstrap(appElement, module ? [module] : []);
  802. }
  803. }
  804. /**
  805. * @ngdoc function
  806. * @name angular.bootstrap
  807. * @description
  808. * Use this function to manually start up angular application.
  809. *
  810. * See: {@link guide/bootstrap Bootstrap}
  811. *
  812. * @param {Element} element DOM element which is the root of angular application.
  813. * @param {Array<String|Function>=} modules an array of module declarations. See: {@link angular.module modules}
  814. * @returns {AUTO.$injector} Returns the newly created injector for this app.
  815. */
  816. function bootstrap(element, modules) {
  817. element = jqLite(element);
  818. modules = modules || [];
  819. modules.unshift(['$provide', function($provide) {
  820. $provide.value('$rootElement', element);
  821. }]);
  822. modules.unshift('ng');
  823. var injector = createInjector(modules);
  824. injector.invoke(
  825. ['$rootScope', '$rootElement', '$compile', '$injector', function(scope, element, compile, injector){
  826. scope.$apply(function() {
  827. element.data('$injector', injector);
  828. compile(element)(scope);
  829. });
  830. }]
  831. );
  832. return injector;
  833. }
  834. var SNAKE_CASE_REGEXP = /[A-Z]/g;
  835. function snake_case(name, separator){
  836. separator = separator || '_';
  837. return name.replace(SNAKE_CASE_REGEXP, function(letter, pos) {
  838. return (pos ? separator : '') + letter.toLowerCase();
  839. });
  840. }
  841. function bindJQuery() {
  842. // bind to jQuery if present;
  843. jQuery = window.jQuery;
  844. // reset to jQuery or default to us.
  845. if (jQuery) {
  846. jqLite = jQuery;
  847. extend(jQuery.fn, {
  848. scope: JQLitePrototype.scope,
  849. controller: JQLitePrototype.controller,
  850. injector: JQLitePrototype.injector,
  851. inheritedData: JQLitePrototype.inheritedData
  852. });
  853. JQLitePatchJQueryRemove('remove', true);
  854. JQLitePatchJQueryRemove('empty');
  855. JQLitePatchJQueryRemove('html');
  856. } else {
  857. jqLite = JQLite;
  858. }
  859. angular.element = jqLite;
  860. }
  861. /**
  862. * throw error of the argument is falsy.
  863. */
  864. function assertArg(arg, name, reason) {
  865. if (!arg) {
  866. throw new Error("Argument '" + (name || '?') + "' is " + (reason || "required"));
  867. }
  868. return arg;
  869. }
  870. function assertArgFn(arg, name, acceptArrayAnnotation) {
  871. if (acceptArrayAnnotation && isArray(arg)) {
  872. arg = arg[arg.length - 1];
  873. }
  874. assertArg(isFunction(arg), name, 'not a function, got ' +
  875. (arg && typeof arg == 'object' ? arg.constructor.name || 'Object' : typeof arg));
  876. return arg;
  877. }
  878. /**
  879. * @ngdoc interface
  880. * @name angular.Module
  881. * @description
  882. *
  883. * Interface for configuring angular {@link angular.module modules}.
  884. */
  885. function setupModuleLoader(window) {
  886. function ensure(obj, name, factory) {
  887. return obj[name] || (obj[name] = factory());
  888. }
  889. return ensure(ensure(window, 'angular', Object), 'module', function() {
  890. /** @type {Object.<string, angular.Module>} */
  891. var modules = {};
  892. /**
  893. * @ngdoc function
  894. * @name angular.module
  895. * @description
  896. *
  897. * The `angular.module` is a global place for creating and registering Angular modules. All
  898. * modules (angular core or 3rd party) that should be available to an application must be
  899. * registered using this mechanism.
  900. *
  901. *
  902. * # Module
  903. *
  904. * A module is a collocation of services, directives, filters, and configuration information. Module
  905. * is used to configure the {@link AUTO.$injector $injector}.
  906. *
  907. * <pre>
  908. * // Create a new module
  909. * var myModule = angular.module('myModule', []);
  910. *
  911. * // register a new service
  912. * myModule.value('appName', 'MyCoolApp');
  913. *
  914. * // configure existing services inside initialization blocks.
  915. * myModule.config(function($locationProvider) {
  916. * // Configure existing providers
  917. * $locationProvider.hashPrefix('!');
  918. * });
  919. * </pre>
  920. *
  921. * Then you can create an injector and load your modules like this:
  922. *
  923. * <pre>
  924. * var injector = angular.injector(['ng', 'MyModule'])
  925. * </pre>
  926. *
  927. * However it's more likely that you'll just use
  928. * {@link ng.directive:ngApp ngApp} or
  929. * {@link angular.bootstrap} to simplify this process for you.
  930. *
  931. * @param {!string} name The name of the module to create or retrieve.
  932. * @param {Array.<string>=} requires If specified then new module is being created. If unspecified then the
  933. * the module is being retrieved for further configuration.
  934. * @param {Function} configFn Optional configuration function for the module. Same as
  935. * {@link angular.Module#config Module#config()}.
  936. * @returns {module} new module with the {@link angular.Module} api.
  937. */
  938. return function module(name, requires, configFn) {
  939. if (requires && modules.hasOwnProperty(name)) {
  940. modules[name] = null;
  941. }
  942. return ensure(modules, name, function() {
  943. if (!requires) {
  944. throw Error('No module: ' + name);
  945. }
  946. /** @type {!Array.<Array.<*>>} */
  947. var invokeQueue = [];
  948. /** @type {!Array.<Function>} */
  949. var runBlocks = [];
  950. var config = invokeLater('$injector', 'invoke');
  951. /** @type {angular.Module} */
  952. var moduleInstance = {
  953. // Private state
  954. _invokeQueue: invokeQueue,
  955. _runBlocks: runBlocks,
  956. /**
  957. * @ngdoc property
  958. * @name angular.Module#requires
  959. * @propertyOf angular.Module
  960. * @returns {Array.<string>} List of module names which must be loaded before this module.
  961. * @description
  962. * Holds the list of modules which the injector will load before the current module is loaded.
  963. */
  964. requires: requires,
  965. /**
  966. * @ngdoc property
  967. * @name angular.Module#name
  968. * @propertyOf angular.Module
  969. * @returns {string} Name of the module.
  970. * @description
  971. */
  972. name: name,
  973. /**
  974. * @ngdoc method
  975. * @name angular.Module#provider
  976. * @methodOf angular.Module
  977. * @param {string} name service name
  978. * @param {Function} providerType Construction function for creating new instance of the service.
  979. * @description
  980. * See {@link AUTO.$provide#provider $provide.provider()}.
  981. */
  982. provider: invokeLater('$provide', 'provider'),
  983. /**
  984. * @ngdoc method
  985. * @name angular.Module#factory
  986. * @methodOf angular.Module
  987. * @param {string} name service name
  988. * @param {Function} providerFunction Function for creating new instance of the service.
  989. * @description
  990. * See {@link AUTO.$provide#factory $provide.factory()}.
  991. */
  992. factory: invokeLater('$provide', 'factory'),
  993. /**
  994. * @ngdoc method
  995. * @name angular.Module#service
  996. * @methodOf angular.Module
  997. * @param {string} name service name
  998. * @param {Function} constructor A constructor function that will be instantiated.
  999. * @description
  1000. * See {@link AUTO.$provide#service $provide.service()}.
  1001. */
  1002. service: invokeLater('$provide', 'service'),
  1003. /**
  1004. * @ngdoc method
  1005. * @name angular.Module#value
  1006. * @methodOf angular.Module
  1007. * @param {string} name service name
  1008. * @param {*} object Service instance object.
  1009. * @description
  1010. * See {@link AUTO.$provide#value $provide.value()}.
  1011. */
  1012. value: invokeLater('$provide', 'value'),
  1013. /**
  1014. * @ngdoc method
  1015. * @name angular.Module#constant
  1016. * @methodOf angular.Module
  1017. * @param {string} name constant name
  1018. * @param {*} object Constant value.
  1019. * @description
  1020. * Because the constant are fixed, they get applied before other provide methods.
  1021. * See {@link AUTO.$provide#constant $provide.constant()}.
  1022. */
  1023. constant: invokeLater('$provide', 'constant', 'unshift'),
  1024. /**
  1025. * @ngdoc method
  1026. * @name angular.Module#filter
  1027. * @methodOf angular.Module
  1028. * @param {string} name Filter name.
  1029. * @param {Function} filterFactory Factory function for creating new instance of filter.
  1030. * @description
  1031. * See {@link ng.$filterProvider#register $filterProvider.register()}.
  1032. */
  1033. filter: invokeLater('$filterProvider', 'register'),
  1034. /**
  1035. * @ngdoc method
  1036. * @name angular.Module#controller
  1037. * @methodOf angular.Module
  1038. * @param {string} name Controller name.
  1039. * @param {Function} constructor Controller constructor function.
  1040. * @description
  1041. * See {@link ng.$controllerProvider#register $controllerProvider.register()}.
  1042. */
  1043. controller: invokeLater('$controllerProvider', 'register'),
  1044. /**
  1045. * @ngdoc method
  1046. * @name angular.Module#directive
  1047. * @methodOf angular.Module
  1048. * @param {string} name directive name
  1049. * @param {Function} directiveFactory Factory function for creating new instance of
  1050. * directives.
  1051. * @description
  1052. * See {@link ng.$compileProvider#directive $compileProvider.directive()}.
  1053. */
  1054. directive: invokeLater('$compileProvider', 'directive'),
  1055. /**
  1056. * @ngdoc method
  1057. * @name angular.Module#config
  1058. * @methodOf angular.Module
  1059. * @param {Function} configFn Execute this function on module load. Useful for service
  1060. * configuration.
  1061. * @description
  1062. * Use this method to register work which needs to be performed on module loading.
  1063. */
  1064. config: config,
  1065. /**
  1066. * @ngdoc method
  1067. * @name angular.Module#run
  1068. * @methodOf angular.Module
  1069. * @param {Function} initializationFn Execute this function after injector creation.
  1070. * Useful for application initialization.
  1071. * @description
  1072. * Use this method to register work which should be performed when the injector is done
  1073. * loading all modules.
  1074. */
  1075. run: function(block) {
  1076. runBlocks.push(block);
  1077. return this;
  1078. }
  1079. };
  1080. if (configFn) {
  1081. config(configFn);
  1082. }
  1083. return moduleInstance;
  1084. /**
  1085. * @param {string} provider
  1086. * @param {string} method
  1087. * @param {String=} insertMethod
  1088. * @returns {angular.Module}
  1089. */
  1090. function invokeLater(provider, method, insertMethod) {
  1091. return function() {
  1092. invokeQueue[insertMethod || 'push']([provider, method, arguments]);
  1093. return moduleInstance;
  1094. }
  1095. }
  1096. });
  1097. };
  1098. });
  1099. }
  1100. /**
  1101. * @ngdoc property
  1102. * @name angular.version
  1103. * @description
  1104. * An object that contains information about the current AngularJS version. This object has the
  1105. * following properties:
  1106. *
  1107. * - `full` – `{string}` – Full version string, such as "0.9.18".
  1108. * - `major` – `{number}` – Major version number, such as "0".
  1109. * - `minor` – `{number}` – Minor version number, such as "9".
  1110. * - `dot` – `{number}` – Dot version number, such as "18".
  1111. * - `codeName` – `{string}` – Code name of the release, such as "jiggling-armfat".
  1112. */
  1113. var version = {
  1114. full: '1.1.2', // all of these placeholder strings will be replaced by rake's
  1115. major: 1, // compile task
  1116. minor: 1,
  1117. dot: 2,
  1118. codeName: 'tofu-animation'
  1119. };
  1120. function publishExternalAPI(angular){
  1121. extend(angular, {
  1122. 'bootstrap': bootstrap,
  1123. 'copy': copy,
  1124. 'extend': extend,
  1125. 'equals': equals,
  1126. 'element': jqLite,
  1127. 'forEach': forEach,
  1128. 'injector': createInjector,
  1129. 'noop':noop,
  1130. 'bind':bind,
  1131. 'toJson': toJson,
  1132. 'fromJson': fromJson,
  1133. 'identity':identity,
  1134. 'isUndefined': isUndefined,
  1135. 'isDefined': isDefined,
  1136. 'isString': isString,
  1137. 'isFunction': isFunction,
  1138. 'isObject': isObject,
  1139. 'isNumber': isNumber,
  1140. 'isElement': isElement,
  1141. 'isArray': isArray,
  1142. 'version': version,
  1143. 'isDate': isDate,
  1144. 'lowercase': lowercase,
  1145. 'uppercase': uppercase,
  1146. 'callbacks': {counter: 0}
  1147. });
  1148. angularModule = setupModuleLoader(window);
  1149. try {
  1150. angularModule('ngLocale');
  1151. } catch (e) {
  1152. angularModule('ngLocale', []).provider('$locale', $LocaleProvider);
  1153. }
  1154. angularModule('ng', ['ngLocale'], ['$provide',
  1155. function ngModule($provide) {
  1156. $provide.provider('$compile', $CompileProvider).
  1157. directive({
  1158. a: htmlAnchorDirective,
  1159. input: inputDirective,
  1160. textarea: inputDirective,
  1161. form: formDirective,
  1162. script: scriptDirective,
  1163. select: selectDirective,
  1164. style: styleDirective,
  1165. option: optionDirective,
  1166. ngBind: ngBindDirective,
  1167. ngBindHtmlUnsafe: ngBindHtmlUnsafeDirective,
  1168. ngBindTemplate: ngBindTemplateDirective,
  1169. ngClass: ngClassDirective,
  1170. ngClassEven: ngClassEvenDirective,
  1171. ngClassOdd: ngClassOddDirective,
  1172. ngCsp: ngCspDirective,
  1173. ngCloak: ngCloakDirective,
  1174. ngController: ngControllerDirective,
  1175. ngForm: ngFormDirective,
  1176. ngHide: ngHideDirective,
  1177. ngInclude: ngIncludeDirective,
  1178. ngInit: ngInitDirective,
  1179. ngNonBindable: ngNonBindableDirective,
  1180. ngPluralize: ngPluralizeDirective,
  1181. ngRepeat: ngRepeatDirective,
  1182. ngShow: ngShowDirective,
  1183. ngSubmit: ngSubmitDirective,
  1184. ngStyle: ngStyleDirective,
  1185. ngSwitch: ngSwitchDirective,
  1186. ngSwitchWhen: ngSwitchWhenDirective,
  1187. ngSwitchDefault: ngSwitchDefaultDirective,
  1188. ngOptions: ngOptionsDirective,
  1189. ngView: ngViewDirective,
  1190. ngTransclude: ngTranscludeDirective,
  1191. ngModel: ngModelDirective,
  1192. ngList: ngListDirective,
  1193. ngChange: ngChangeDirective,
  1194. required: requiredDirective,
  1195. ngRequired: requiredDirective,
  1196. ngValue: ngValueDirective
  1197. }).
  1198. directive(ngAttributeAliasDirectives).
  1199. directive(ngEventDirectives);
  1200. $provide.provider({
  1201. $anchorScroll: $AnchorScrollProvider,
  1202. $browser: $BrowserProvider,
  1203. $cacheFactory: $CacheFactoryProvider,
  1204. $controller: $ControllerProvider,
  1205. $document: $DocumentProvider,
  1206. $exceptionHandler: $ExceptionHandlerProvider,
  1207. $filter: $FilterProvider,
  1208. $interpolate: $InterpolateProvider,
  1209. $http: $HttpProvider,
  1210. $httpBackend: $HttpBackendProvider,
  1211. $location: $LocationProvider,
  1212. $log: $LogProvider,
  1213. $parse: $ParseProvider,
  1214. $route: $RouteProvider,
  1215. $routeParams: $RouteParamsProvider,
  1216. $rootScope: $RootScopeProvider,
  1217. $q: $QProvider,
  1218. $sniffer: $SnifferProvider,
  1219. $templateCache: $TemplateCacheProvider,
  1220. $timeout: $TimeoutProvider,
  1221. $window: $WindowProvider
  1222. });
  1223. }
  1224. ]);
  1225. }
  1226. //////////////////////////////////
  1227. //JQLite
  1228. //////////////////////////////////
  1229. /**
  1230. * @ngdoc function
  1231. * @name angular.element
  1232. * @function
  1233. *
  1234. * @description
  1235. * Wraps a raw DOM element or HTML string as a [jQuery](http://jquery.com) element.
  1236. * `angular.element` can be either an alias for [jQuery](http://api.jquery.com/jQuery/) function, if
  1237. * jQuery is available, or a function that wraps the element or string in Angular's jQuery lite
  1238. * implementation (commonly referred to as jqLite).
  1239. *
  1240. * Real jQuery always takes precedence over jqLite, provided it was loaded before `DOMContentLoaded`
  1241. * event fired.
  1242. *
  1243. * jqLite is a tiny, API-compatible subset of jQuery that allows
  1244. * Angular to manipulate the DOM. jqLite implements only the most commonly needed functionality
  1245. * within a very small footprint, so only a subset of the jQuery API - methods, arguments and
  1246. * invocation styles - are supported.
  1247. *
  1248. * Note: All element references in Angular are always wrapped with jQuery or jqLite; they are never
  1249. * raw DOM references.
  1250. *
  1251. * ## Angular's jQuery lite provides the following methods:
  1252. *
  1253. * - [addClass()](http://api.jquery.com/addClass/)
  1254. * - [after()](http://api.jquery.com/after/)
  1255. * - [append()](http://api.jquery.com/append/)
  1256. * - [attr()](http://api.jquery.com/attr/)
  1257. * - [bind()](http://api.jquery.com/bind/)
  1258. * - [children()](http://api.jquery.com/children/)
  1259. * - [clone()](http://api.jquery.com/clone/)
  1260. * - [contents()](http://api.jquery.com/contents/)
  1261. * - [css()](http://api.jquery.com/css/)
  1262. * - [data()](http://api.jquery.com/data/)
  1263. * - [eq()](http://api.jquery.com/eq/)
  1264. * - [find()](http://api.jquery.com/find/) - Limited to lookups by tag name.
  1265. * - [hasClass()](http://api.jquery.com/hasClass/)
  1266. * - [html()](http://api.jquery.com/html/)
  1267. * - [next()](http://api.jquery.com/next/)
  1268. * - [parent()](http://api.jquery.com/parent/)
  1269. * - [prepend()](http://api.jquery.com/prepend/)
  1270. * - [prop()](http://api.jquery.com/prop/)
  1271. * - [ready()](http://api.jquery.com/ready/)
  1272. * - [remove()](http://api.jquery.com/remove/)
  1273. * - [removeAttr()](http://api.jquery.com/removeAttr/)
  1274. * - [removeClass()](http://api.jquery.com/removeClass/)
  1275. * - [removeData()](http://api.jquery.com/removeData/)
  1276. * - [replaceWith()](http://api.jquery.com/replaceWith/)
  1277. * - [text()](http://api.jquery.com/text/)
  1278. * - [toggleClass()](http://api.jquery.com/toggleClass/)
  1279. * - [triggerHandler()](http://api.jquery.com/triggerHandler/) - Doesn't pass native event objects to handlers.
  1280. * - [unbind()](http://api.jquery.com/unbind/)
  1281. * - [val()](http://api.jquery.com/val/)
  1282. * - [wrap()](http://api.jquery.com/wrap/)
  1283. *
  1284. * ## In addtion to the above, Angular provides additional methods to both jQuery and jQuery lite:
  1285. *
  1286. * - `controller(name)` - retrieves the controller of the current element or its parent. By default
  1287. * retrieves controller associated with the `ngController` directive. If `name` is provided as
  1288. * camelCase directive name, then the controller for this directive will be retrieved (e.g.
  1289. * `'ngModel'`).
  1290. * - `injector()` - retrieves the injector of the current element or its parent.
  1291. * - `scope()` - retrieves the {@link api/ng.$rootScope.Scope scope} of the current
  1292. * element or its parent.
  1293. * - `inheritedData()` - same as `data()`, but walks up the DOM until a value is found or the top
  1294. * parent element is reached.
  1295. *
  1296. * @param {string|DOMElement} element HTML string or DOMElement to be wrapped into jQuery.
  1297. * @returns {Object} jQuery object.
  1298. */
  1299. var jqCache = JQLite.cache = {},
  1300. jqName = JQLite.expando = 'ng-' + new Date().getTime(),
  1301. jqId = 1,
  1302. addEventListenerFn = (window.document.addEventListener
  1303. ? function(element, type, fn) {element.addEventListener(type, fn, false);}
  1304. : function(element, type, fn) {element.attachEvent('on' + type, fn);}),
  1305. removeEventListenerFn = (window.document.removeEventListener
  1306. ? function(element, type, fn) {element.removeEventListener(type, fn, false); }
  1307. : function(element, type, fn) {element.detachEvent('on' + type, fn); });
  1308. function jqNextId() { return ++jqId; }
  1309. var SPECIAL_CHARS_REGEXP = /([\:\-\_]+(.))/g;
  1310. var MOZ_HACK_REGEXP = /^moz([A-Z])/;
  1311. /**
  1312. * Converts snake_case to camelCase.
  1313. * Also there is special case for Moz prefix starting with upper case letter.
  1314. * @param name Name to normalize
  1315. */
  1316. function camelCase(name) {
  1317. return name.
  1318. replace(SPECIAL_CHARS_REGEXP, function(_, separator, letter, offset) {
  1319. return offset ? letter.toUpperCase() : letter;
  1320. }).
  1321. replace(MOZ_HACK_REGEXP, 'Moz$1');
  1322. }
  1323. /////////////////////////////////////////////
  1324. // jQuery mutation patch
  1325. //
  1326. // In conjunction with bindJQuery intercepts all jQuery's DOM destruction apis and fires a
  1327. // $destroy event on all DOM nodes being removed.
  1328. //
  1329. /////////////////////////////////////////////
  1330. function JQLitePatchJQueryRemove(name, dispatchThis) {
  1331. var originalJqFn = jQuery.fn[name];
  1332. originalJqFn = originalJqFn.$original || originalJqFn;
  1333. removePatch.$original = originalJqFn;
  1334. jQuery.fn[name] = removePatch;
  1335. function removePatch() {
  1336. var list = [this],
  1337. fireEvent = dispatchThis,
  1338. set, setIndex, setLength,
  1339. element, childIndex, childLength, children,
  1340. fns, events;
  1341. while(list.length) {
  1342. set = list.shift();
  1343. for(setIndex = 0, setLength = set.length; setIndex < setLength; setIndex++) {
  1344. element = jqLite(set[setIndex]);
  1345. if (fireEvent) {
  1346. element.triggerHandler('$destroy');
  1347. } else {
  1348. fireEvent = !fireEvent;
  1349. }
  1350. for(childIndex = 0, childLength = (children = element.children()).length;
  1351. childIndex < childLength;
  1352. childIndex++) {
  1353. list.push(jQuery(children[childIndex]));
  1354. }
  1355. }
  1356. }
  1357. return originalJqFn.apply(this, arguments);
  1358. }
  1359. }
  1360. /////////////////////////////////////////////
  1361. function JQLite(element) {
  1362. if (element instanceof JQLite) {
  1363. return element;
  1364. }
  1365. if (!(this instanceof JQLite)) {
  1366. if (isString(element) && element.charAt(0) != '<') {
  1367. throw Error('selectors not implemented');
  1368. }
  1369. return new JQLite(element);
  1370. }
  1371. if (isString(element)) {
  1372. var div = document.createElement('div');
  1373. // Read about the NoScope elements here:
  1374. // http://msdn.microsoft.com/en-us/library/ms533897(VS.85).aspx
  1375. div.innerHTML = '<div>&#160;</div>' + element; // IE insanity to make NoScope elements work!
  1376. div.removeChild(div.firstChild); // remove the superfluous div
  1377. JQLiteAddNodes(this, div.childNodes);
  1378. this.remove(); // detach the elements from the temporary DOM div.
  1379. } else {
  1380. JQLiteAddNodes(this, element);
  1381. }
  1382. }
  1383. function JQLiteClone(element) {
  1384. return element.cloneNode(true);
  1385. }
  1386. function JQLiteDealoc(element){
  1387. JQLiteRemoveData(element);
  1388. for ( var i = 0, children = element.childNodes || []; i < children.length; i++) {
  1389. JQLiteDealoc(children[i]);
  1390. }
  1391. }
  1392. function JQLiteUnbind(element, type, fn) {
  1393. var events = JQLiteExpandoStore(element, 'events'),
  1394. handle = JQLiteExpandoStore(element, 'handle');
  1395. if (!handle) return; //no listeners registered
  1396. if (isUndefined(type)) {
  1397. forEach(events, function(eventHandler, type) {
  1398. removeEventListenerFn(element, type, eventHandler);
  1399. delete events[type];
  1400. });
  1401. } else {
  1402. if (isUndefined(fn)) {
  1403. removeEventListenerFn(element, type, events[type]);
  1404. delete events[type];
  1405. } else {
  1406. arrayRemove(events[type], fn);
  1407. }
  1408. }
  1409. }
  1410. function JQLiteRemoveData(element) {
  1411. var expandoId = element[jqName],
  1412. expandoStore = jqCache[expandoId];
  1413. if (expandoStore) {
  1414. if (expandoStore.handle) {
  1415. expandoStore.events.$destroy && expandoStore.handle({}, '$destroy');
  1416. JQLiteUnbind(element);
  1417. }
  1418. delete jqCache[expandoId];
  1419. element[jqName] = undefined; // ie does not allow deletion of attributes on elements.
  1420. }
  1421. }
  1422. function JQLiteExpandoStore(element, key, value) {
  1423. var expandoId = element[jqName],
  1424. expandoStore = jqCache[expandoId || -1];
  1425. if (isDefined(value)) {
  1426. if (!expandoStore) {
  1427. element[jqName] = expandoId = jqNextId();
  1428. expandoStore = jqCache[expandoId] = {};
  1429. }
  1430. expandoStore[key] = value;
  1431. } else {
  1432. return expandoStore && expandoStore[key];
  1433. }
  1434. }
  1435. function JQLiteData(element, key, value) {
  1436. var data = JQLiteExpandoStore(element, 'data'),
  1437. isSetter = isDefined(value),
  1438. keyDefined = !isSetter && isDefined(key),
  1439. isSimpleGetter = keyDefined && !isObject(key);
  1440. if (!data && !isSimpleGetter) {
  1441. JQLiteExpandoStore(element, 'data', data = {});
  1442. }
  1443. if (isSetter) {
  1444. data[key] = value;
  1445. } else {
  1446. if (keyDefined) {
  1447. if (isSimpleGetter) {
  1448. // don't create data in this case.
  1449. return data && data[key];
  1450. } else {
  1451. ex