summaryrefslogtreecommitdiffstats
path: root/js/vendor/angular/angular.js
diff options
context:
space:
mode:
authorBernhard Posselt <dev@bernhard-posselt.com>2014-03-14 10:22:09 +0100
committerBernhard Posselt <dev@bernhard-posselt.com>2014-03-26 01:34:31 +0100
commit2fc5ca4f601174a7ecb7c77a7059f5fac2ab4611 (patch)
treeaa7ab66e29fc7de98533d1e55832ca4fbcd39611 /js/vendor/angular/angular.js
parent22fc777ce7403d706649cf83bb23010dfd7dea04 (diff)
update a lot of stuff, WIP
Diffstat (limited to 'js/vendor/angular/angular.js')
-rw-r--r--[-rwxr-xr-x]js/vendor/angular/angular.js16195
1 files changed, 11045 insertions, 5150 deletions
diff --git a/js/vendor/angular/angular.js b/js/vendor/angular/angular.js
index 719bc648e..83146684b 100755..100644
--- a/js/vendor/angular/angular.js
+++ b/js/vendor/angular/angular.js
@@ -1,16 +1,190 @@
/**
- * @license AngularJS v1.0.8
- * (c) 2010-2012 Google, Inc. http://angularjs.org
+ * @license AngularJS v1.2.14
+ * (c) 2010-2014 Google, Inc. http://angularjs.org
* License: MIT
*/
-(function(window, document, undefined) {
-'use strict';
+(function(window, document, undefined) {'use strict';
+
+/**
+ * @description
+ *
+ * This object provides a utility for producing rich Error messages within
+ * Angular. It can be called as follows:
+ *
+ * var exampleMinErr = minErr('example');
+ * throw exampleMinErr('one', 'This {0} is {1}', foo, bar);
+ *
+ * The above creates an instance of minErr in the example namespace. The
+ * resulting error will have a namespaced error code of example.one. The
+ * resulting error will replace {0} with the value of foo, and {1} with the
+ * value of bar. The object is not restricted in the number of arguments it can
+ * take.
+ *
+ * If fewer arguments are specified than necessary for interpolation, the extra
+ * interpolation markers will be preserved in the final string.
+ *
+ * Since data will be parsed statically during a build step, some restrictions
+ * are applied with respect to how minErr instances are created and called.
+ * Instances should have names of the form namespaceMinErr for a minErr created
+ * using minErr('namespace') . Error codes, namespaces and template strings
+ * should all be static strings, not variables or general expressions.
+ *
+ * @param {string} module The namespace to use for the new minErr instance.
+ * @returns {function(code:string, template:string, ...templateArgs): Error} minErr instance
+ */
+
+function minErr(module) {
+ return function () {
+ var code = arguments[0],
+ prefix = '[' + (module ? module + ':' : '') + code + '] ',
+ template = arguments[1],
+ templateArgs = arguments,
+ stringify = function (obj) {
+ if (typeof obj === 'function') {
+ return obj.toString().replace(/ \{[\s\S]*$/, '');
+ } else if (typeof obj === 'undefined') {
+ return 'undefined';
+ } else if (typeof obj !== 'string') {
+ return JSON.stringify(obj);
+ }
+ return obj;
+ },
+ message, i;
+
+ message = prefix + template.replace(/\{\d+\}/g, function (match) {
+ var index = +match.slice(1, -1), arg;
+
+ if (index + 2 < templateArgs.length) {
+ arg = templateArgs[index + 2];
+ if (typeof arg === 'function') {
+ return arg.toString().replace(/ ?\{[\s\S]*$/, '');
+ } else if (typeof arg === 'undefined') {
+ return 'undefined';
+ } else if (typeof arg !== 'string') {
+ return toJson(arg);
+ }
+ return arg;
+ }
+ return match;
+ });
+
+ message = message + '\nhttp://errors.angularjs.org/1.2.14/' +
+ (module ? module + '/' : '') + code;
+ for (i = 2; i < arguments.length; i++) {
+ message = message + (i == 2 ? '?' : '&') + 'p' + (i-2) + '=' +
+ encodeURIComponent(stringify(arguments[i]));
+ }
+
+ return new Error(message);
+ };
+}
+
+/* We need to tell jshint what variables are being exported */
+/* global
+ -angular,
+ -msie,
+ -jqLite,
+ -jQuery,
+ -slice,
+ -push,
+ -toString,
+ -ngMinErr,
+ -_angular,
+ -angularModule,
+ -nodeName_,
+ -uid,
+
+ -lowercase,
+ -uppercase,
+ -manualLowercase,
+ -manualUppercase,
+ -nodeName_,
+ -isArrayLike,
+ -forEach,
+ -sortedKeys,
+ -forEachSorted,
+ -reverseParams,
+ -nextUid,
+ -setHashKey,
+ -extend,
+ -int,
+ -inherit,
+ -noop,
+ -identity,
+ -valueFn,
+ -isUndefined,
+ -isDefined,
+ -isObject,
+ -isString,
+ -isNumber,
+ -isDate,
+ -isArray,
+ -isFunction,
+ -isRegExp,
+ -isWindow,
+ -isScope,
+ -isFile,
+ -isBoolean,
+ -trim,
+ -isElement,
+ -makeMap,
+ -map,
+ -size,
+ -includes,
+ -indexOf,
+ -arrayRemove,
+ -isLeafNode,
+ -copy,
+ -shallowCopy,
+ -equals,
+ -csp,
+ -concat,
+ -sliceArgs,
+ -bind,
+ -toJsonReplacer,
+ -toJson,
+ -fromJson,
+ -toBoolean,
+ -startingTag,
+ -tryDecodeURIComponent,
+ -parseKeyValue,
+ -toKeyValue,
+ -encodeUriSegment,
+ -encodeUriQuery,
+ -angularInit,
+ -bootstrap,
+ -snake_case,
+ -bindJQuery,
+ -assertArg,
+ -assertArgFn,
+ -assertNotHasOwnProperty,
+ -getter,
+ -getBlockElements,
+ -hasOwnProperty,
+
+*/
////////////////////////////////////
/**
+ * @ngdoc module
+ * @name ng
+ * @module ng
+ * @description
+ *
+ * # ng (core module)
+ * The ng module is loaded by default when an AngularJS application is started. The module itself
+ * contains the essential components for an AngularJS application to function. The table below
+ * lists a high level breakdown of each of the services/factories, filters, directives and testing
+ * components available within this core module.
+ *
+ * <div doc-module-components="ng"></div>
+ */
+
+/**
* @ngdoc function
* @name angular.lowercase
+ * @module ng
* @function
*
* @description Converts the specified string to lowercase.
@@ -18,11 +192,12 @@
* @returns {string} Lowercased string.
*/
var lowercase = function(string){return isString(string) ? string.toLowerCase() : string;};
-
+var hasOwnProperty = Object.prototype.hasOwnProperty;
/**
* @ngdoc function
* @name angular.uppercase
+ * @module ng
* @function
*
* @description Converts the specified string to uppercase.
@@ -33,11 +208,13 @@ var uppercase = function(string){return isString(string) ? string.toUpperCase()
var manualLowercase = function(s) {
+ /* jshint bitwise: false */
return isString(s)
? s.replace(/[A-Z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) | 32);})
: s;
};
var manualUppercase = function(s) {
+ /* jshint bitwise: false */
return isString(s)
? s.replace(/[a-z]/g, function(ch) {return String.fromCharCode(ch.charCodeAt(0) & ~32);})
: s;
@@ -54,45 +231,57 @@ if ('i' !== 'I'.toLowerCase()) {
var /** holds major version number for IE or NaN for real browsers */
- msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]),
+ msie,
jqLite, // delay binding since jQuery could be loaded after us.
jQuery, // delay binding
slice = [].slice,
push = [].push,
toString = Object.prototype.toString,
+ ngMinErr = minErr('ng'),
+
+ _angular = window.angular,
/** @name angular */
angular = window.angular || (window.angular = {}),
angularModule,
nodeName_,
uid = ['0', '0', '0'];
+/**
+ * IE 11 changed the format of the UserAgent string.
+ * See http://msdn.microsoft.com/en-us/library/ms537503.aspx
+ */
+msie = int((/msie (\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
+if (isNaN(msie)) {
+ msie = int((/trident\/.*; rv:(\d+)/.exec(lowercase(navigator.userAgent)) || [])[1]);
+}
+
/**
* @private
* @param {*} obj
- * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments, ...)
+ * @return {boolean} Returns true if `obj` is an array or array-like object (NodeList, Arguments,
+ * String ...)
*/
function isArrayLike(obj) {
- if (!obj || (typeof obj.length !== 'number')) return false;
+ if (obj == null || isWindow(obj)) {
+ return false;
+ }
+
+ var length = obj.length;
- // We have on object which has length property. Should we treat it as array?
- if (typeof obj.hasOwnProperty != 'function' &&
- typeof obj.constructor != 'function') {
- // This is here for IE8: it is a bogus object treat it as array;
+ if (obj.nodeType === 1 && length) {
return true;
- } else {
- return obj instanceof JQLite || // JQLite
- (jQuery && obj instanceof jQuery) || // jQuery
- toString.call(obj) !== '[object Object]' || // some browser native object
- typeof obj.callee === 'function'; // arguments (on IE8 looks like regular obj)
}
-}
+ return isString(obj) || isArray(obj) || length === 0 ||
+ typeof length === 'number' && length > 0 && (length - 1) in obj;
+}
/**
* @ngdoc function
* @name angular.forEach
+ * @module ng
* @function
*
* @description
@@ -101,16 +290,17 @@ function isArrayLike(obj) {
* is the value of an object property or an array element and `key` is the object property key or
* array element index. Specifying a `context` for the function is optional.
*
- * Note: this function was previously known as `angular.foreach`.
+ * It is worth noting that `.forEach` does not iterate over inherited properties because it filters
+ * using the `hasOwnProperty` method.
*
- <pre>
+ ```js
var values = {name: 'misko', gender: 'male'};
var log = [];
angular.forEach(values, function(value, key){
this.push(key + ': ' + value);
}, log);
- expect(log).toEqual(['name: misko', 'gender:male']);
- </pre>
+ expect(log).toEqual(['name: misko', 'gender: male']);
+ ```
*
* @param {Object|Array} obj Object to iterate over.
* @param {Function} iterator Iterator function.
@@ -122,7 +312,9 @@ function forEach(obj, iterator, context) {
if (obj) {
if (isFunction(obj)){
for (key in obj) {
- if (key != 'prototype' && key != 'length' && key != 'name' && obj.hasOwnProperty(key)) {
+ // Need to check if hasOwnProperty exists,
+ // as on IE8 the result of querySelectorAll is an object without a hasOwnProperty function
+ if (key != 'prototype' && key != 'length' && key != 'name' && (!obj.hasOwnProperty || obj.hasOwnProperty(key))) {
iterator.call(context, obj[key], key);
}
}
@@ -167,7 +359,7 @@ function forEachSorted(obj, iterator, context) {
* @returns {function(*, string)}
*/
function reverseParams(iteratorFn) {
- return function(value, key) { iteratorFn(key, value) };
+ return function(value, key) { iteratorFn(key, value); };
}
/**
@@ -176,7 +368,7 @@ function reverseParams(iteratorFn) {
* the number string gets longer over time, and it can also overflow, where as the nextId
* will grow much slower, it is a string, and it will never overflow.
*
- * @returns an unique alpha-numeric string
+ * @returns {string} an unique alpha-numeric string
*/
function nextUid() {
var index = uid.length;
@@ -203,7 +395,7 @@ function nextUid() {
/**
* Set or clear the hashkey for an object.
- * @param obj object
+ * @param obj object
* @param h the hashkey (!truthy to delete the hashkey)
*/
function setHashKey(obj, h) {
@@ -218,6 +410,7 @@ function setHashKey(obj, h) {
/**
* @ngdoc function
* @name angular.extend
+ * @module ng
* @function
*
* @description
@@ -251,21 +444,21 @@ function inherit(parent, extra) {
return extend(new (extend(function() {}, {prototype:parent}))(), extra);
}
-
/**
* @ngdoc function
* @name angular.noop
+ * @module ng
* @function
*
* @description
* A function that performs no operations. This function can be useful when writing code in the
* functional style.
- <pre>
+ ```js
function foo(callback) {
var result = calculateResult();
(callback || angular.noop)(result);
}
- </pre>
+ ```
*/
function noop() {}
noop.$inject = [];
@@ -274,17 +467,18 @@ noop.$inject = [];
/**
* @ngdoc function
* @name angular.identity
+ * @module ng
* @function
*
* @description
* A function that returns its first argument. This function is useful when writing code in the
* functional style.
*
- <pre>
+ ```js
function transformer(transformationFn, value) {
return (transformationFn || angular.identity)(value);
};
- </pre>
+ ```
*/
function identity($) {return $;}
identity.$inject = [];
@@ -295,6 +489,7 @@ function valueFn(value) {return function() {return value;};}
/**
* @ngdoc function
* @name angular.isUndefined
+ * @module ng
* @function
*
* @description
@@ -303,12 +498,13 @@ function valueFn(value) {return function() {return value;};}
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is undefined.
*/
-function isUndefined(value){return typeof value == 'undefined';}
+function isUndefined(value){return typeof value === 'undefined';}
/**
* @ngdoc function
* @name angular.isDefined
+ * @module ng
* @function
*
* @description
@@ -317,27 +513,29 @@ function isUndefined(value){return typeof value == 'undefined';}
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is defined.
*/
-function isDefined(value){return typeof value != 'undefined';}
+function isDefined(value){return typeof value !== 'undefined';}
/**
* @ngdoc function
* @name angular.isObject
+ * @module ng
* @function
*
* @description
* Determines if a reference is an `Object`. Unlike `typeof` in JavaScript, `null`s are not
- * considered to be objects.
+ * considered to be objects. Note that JavaScript arrays are objects.
*
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is an `Object` but not `null`.
*/
-function isObject(value){return value != null && typeof value == 'object';}
+function isObject(value){return value != null && typeof value === 'object';}
/**
* @ngdoc function
* @name angular.isString
+ * @module ng
* @function
*
* @description
@@ -346,12 +544,13 @@ function isObject(value){return value != null && typeof value == 'object';}
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `String`.
*/
-function isString(value){return typeof value == 'string';}
+function isString(value){return typeof value === 'string';}
/**
* @ngdoc function
* @name angular.isNumber
+ * @module ng
* @function
*
* @description
@@ -360,12 +559,13 @@ function isString(value){return typeof value == 'string';}
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `Number`.
*/
-function isNumber(value){return typeof value == 'number';}
+function isNumber(value){return typeof value === 'number';}
/**
* @ngdoc function
* @name angular.isDate
+ * @module ng
* @function
*
* @description
@@ -375,13 +575,14 @@ function isNumber(value){return typeof value == 'number';}
* @returns {boolean} True if `value` is a `Date`.
*/
function isDate(value){
- return toString.apply(value) == '[object Date]';
+ return toString.call(value) === '[object Date]';
}
/**
* @ngdoc function
* @name angular.isArray
+ * @module ng
* @function
*
* @description
@@ -391,13 +592,14 @@ function isDate(value){
* @returns {boolean} True if `value` is an `Array`.
*/
function isArray(value) {
- return toString.apply(value) == '[object Array]';
+ return toString.call(value) === '[object Array]';
}
/**
* @ngdoc function
* @name angular.isFunction
+ * @module ng
* @function
*
* @description
@@ -406,7 +608,7 @@ function isArray(value) {
* @param {*} value Reference to check.
* @returns {boolean} True if `value` is a `Function`.
*/
-function isFunction(value){return typeof value == 'function';}
+function isFunction(value){return typeof value === 'function';}
/**
@@ -417,7 +619,7 @@ function isFunction(value){return typeof value == 'function';}
* @returns {boolean} True if `value` is a `RegExp`.
*/
function isRegExp(value) {
- return toString.apply(value) == '[object RegExp]';
+ return toString.call(value) === '[object RegExp]';
}
@@ -439,12 +641,12 @@ function isScope(obj) {
function isFile(obj) {
- return toString.apply(obj) === '[object File]';
+ return toString.call(obj) === '[object File]';
}
function isBoolean(value) {
- return typeof value == 'boolean';
+ return typeof value === 'boolean';
}
@@ -454,7 +656,7 @@ var trim = (function() {
// TODO: we should move this into IE/ES5 polyfill
if (!String.prototype.trim) {
return function(value) {
- return isString(value) ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
+ return isString(value) ? value.replace(/^\s\s*/, '').replace(/\s\s*$/, '') : value;
};
}
return function(value) {
@@ -466,6 +668,7 @@ var trim = (function() {
/**
* @ngdoc function
* @name angular.isElement
+ * @module ng
* @function
*
* @description
@@ -475,9 +678,9 @@ var trim = (function() {
* @returns {boolean} True if `value` is a DOM element (or wrapped jQuery element).
*/
function isElement(node) {
- return node &&
+ return !!(node &&
(node.nodeName // we are a direct element
- || (node.bind && node.find)); // we have a bind and find method part of jQuery API
+ || (node.prop && node.attr && node.find))); // we have an on and find method part of jQuery API
}
/**
@@ -527,17 +730,17 @@ function map(obj, iterator, context) {
* @returns {number} The size of `obj` or `0` if `obj` is neither an object nor an array.
*/
function size(obj, ownPropsOnly) {
- var size = 0, key;
+ var count = 0, key;
if (isArray(obj) || isString(obj)) {
return obj.length;
} else if (isObject(obj)){
for (key in obj)
if (!ownPropsOnly || obj.hasOwnProperty(key))
- size++;
+ count++;
}
- return size;
+ return count;
}
@@ -548,7 +751,7 @@ function includes(array, obj) {
function indexOf(array, obj) {
if (array.indexOf) return array.indexOf(obj);
- for ( var i = 0; i < array.length; i++) {
+ for (var i = 0; i < array.length; i++) {
if (obj === array[i]) return i;
}
return -1;
@@ -576,6 +779,7 @@ function isLeafNode (node) {
/**
* @ngdoc function
* @name angular.copy
+ * @module ng
* @function
*
* @description
@@ -584,19 +788,57 @@ function isLeafNode (node) {
* * If no destination is supplied, a copy of the object or array is created.
* * If a destination is provided, all of its elements (for array) or properties (for objects)
* are deleted and then all elements/properties from the source are copied to it.
- * * If `source` is not an object or array, `source` is returned.
- *
- * Note: this function is used to augment the Object type in Angular expressions. See
- * {@link ng.$filter} for more information about Angular arrays.
+ * * If `source` is not an object or array (inc. `null` and `undefined`), `source` is returned.
+ * * If `source` is identical to 'destination' an exception will be thrown.
*
* @param {*} source The source that will be used to make a copy.
* Can be any type, including primitives, `null`, and `undefined`.
* @param {(Object|Array)=} destination Destination into which the source is copied. If
* provided, must be of the same type as `source`.
* @returns {*} The copy or updated `destination`, if `destination` was specified.
+ *
+ * @example
+ <example>
+ <file name="index.html">
+ <div ng-controller="Controller">
+ <form novalidate class="simple-form">
+ Name: <input type="text" ng-model="user.name" /><br />
+ E-mail: <input type="email" ng-model="user.email" /><br />
+ Gender: <input type="radio" ng-model="user.gender" value="male" />male
+ <input type="radio" ng-model="user.gender" value="female" />female<br />
+ <button ng-click="reset()">RESET</button>
+ <button ng-click="update(user)">SAVE</button>
+ </form>
+ <pre>form = {{user | json}}</pre>
+ <pre>master = {{master | json}}</pre>
+ </div>
+
+ <script>
+ function Controller($scope) {
+ $scope.master= {};
+
+ $scope.update = function(user) {
+ // Example with 1 argument
+ $scope.master= angular.copy(user);
+ };
+
+ $scope.reset = function() {
+ // Example with 2 arguments
+ angular.copy($scope.master, $scope.user);
+ };
+
+ $scope.reset();
+ }
+ </script>
+ </file>
+ </example>
*/
function copy(source, destination){
- if (isWindow(source) || isScope(source)) throw Error("Can't copy Window or Scope");
+ if (isWindow(source) || isScope(source)) {
+ throw ngMinErr('cpws',
+ "Can't copy! Making copies of Window or Scope instances is not supported.");
+ }
+
if (!destination) {
destination = source;
if (source) {
@@ -611,7 +853,8 @@ function copy(source, destination){
}
}
} else {
- if (source === destination) throw Error("Can't copy equivalent objects or arrays");
+ if (source === destination) throw ngMinErr('cpi',
+ "Can't copy! Source and destination are identical.");
if (isArray(source)) {
destination.length = 0;
for ( var i = 0; i < source.length; i++) {
@@ -638,7 +881,9 @@ function shallowCopy(src, dst) {
dst = dst || {};
for(var key in src) {
- if (src.hasOwnProperty(key) && key.substr(0, 2) !== '$$') {
+ // shallowCopy is only ever called by $compile nodeLinkFn, which has control over src
+ // so we don't need to worry about using our custom hasOwnProperty here
+ if (src.hasOwnProperty(key) && !(key.charAt(0) === '$' && key.charAt(1) === '$')) {
dst[key] = src[key];
}
}
@@ -650,22 +895,24 @@ function shallowCopy(src, dst) {
/**
* @ngdoc function
* @name angular.equals
+ * @module ng
* @function
*
* @description
- * Determines if two objects or two values are equivalent. Supports value types, regular expressions, arrays and
- * objects.
+ * Determines if two objects or two values are equivalent. Supports value types, regular
+ * expressions, arrays and objects.
*
* Two objects or values are considered equivalent if at least one of the following is true:
*
* * Both objects or values pass `===` comparison.
- * * Both objects or values are of the same type and all of their properties pass `===` comparison.
- * * Both values are NaN. (In JavasScript, NaN == NaN => false. But we consider two NaN as equal)
+ * * Both objects or values are of the same type and all of their properties are equal by
+ * comparing them with `angular.equals`.
+ * * Both values are NaN. (In JavaScript, NaN == NaN => false. But we consider two NaN as equal)
* * Both values represent the same regular expression (In JavasScript,
* /abc/ == /abc/ => false. But we consider two regular expressions as equal when their textual
* representation matches).
*
- * During a property comparision, properties of `function` type and properties with names
+ * During a property comparison, properties of `function` type and properties with names
* that begin with `$` are ignored.
*
* Scope and DOMWindow objects are being compared only by identify (`===`).
@@ -702,7 +949,7 @@ function equals(o1, o2) {
keySet[key] = true;
}
for(key in o2) {
- if (!keySet[key] &&
+ if (!keySet.hasOwnProperty(key) &&
key.charAt(0) !== '$' &&
o2[key] !== undefined &&
!isFunction(o2[key])) return false;
@@ -715,6 +962,13 @@ function equals(o1, o2) {
}
+function csp() {
+ return (document.securityPolicy && document.securityPolicy.isActive) ||
+ (document.querySelector &&
+ !!(document.querySelector('[ng-csp]') || document.querySelector('[data-ng-csp]')));
+}
+
+
function concat(array1, array2, index) {
return array1.concat(slice.call(array2, index));
}
@@ -724,21 +978,25 @@ function sliceArgs(args, startIndex) {
}
+/* jshint -W101 */
/**
* @ngdoc function
* @name angular.bind
+ * @module ng
* @function
*
* @description
* Returns a function which calls function `fn` bound to `self` (`self` becomes the `this` for
* `fn`). You can supply optional `args` that are prebound to the function. This feature is also
- * known as [function currying](http://en.wikipedia.org/wiki/Currying).
+ * known as [partial application](http://en.wikipedia.org/wiki/Partial_application), as
+ * distinguished from [function currying](http://en.wikipedia.org/wiki/Currying#Contrast_with_partial_function_application).
*
* @param {Object} self Context which `fn` should be evaluated in.
* @param {function()} fn Function to be bound.
* @param {...*} args Optional arguments to be prebound to the `fn` function call.
* @returns {function()} Function that wraps the `fn` with all the specified bindings.
*/
+/* jshint +W101 */
function bind(self, fn) {
var curryArgs = arguments.length > 2 ? sliceArgs(arguments, 2) : [];
if (isFunction(fn) && !(fn instanceof RegExp)) {
@@ -763,7 +1021,7 @@ function bind(self, fn) {
function toJsonReplacer(key, value) {
var val = value;
- if (/^\$+/.test(key)) {
+ if (typeof key === 'string' && key.charAt(0) === '$') {
val = undefined;
} else if (isWindow(value)) {
val = '$WINDOW';
@@ -780,6 +1038,7 @@ function toJsonReplacer(key, value) {
/**
* @ngdoc function
* @name angular.toJson
+ * @module ng
* @function
*
* @description
@@ -788,7 +1047,7 @@ function toJsonReplacer(key, value) {
*
* @param {Object|Array|Date|string|number} obj Input to be serialized into JSON.
* @param {boolean=} pretty If set to true, the JSON output will contain newlines and whitespace.
- * @returns {string|undefined} Jsonified string representing `obj`.
+ * @returns {string|undefined} JSON-ified string representing `obj`.
*/
function toJson(obj, pretty) {
if (typeof obj === 'undefined') return undefined;
@@ -799,13 +1058,14 @@ function toJson(obj, pretty) {
/**
* @ngdoc function
* @name angular.fromJson
+ * @module ng
* @function
*
* @description
* Deserializes a JSON string.
*
* @param {string} json JSON string to deserialize.
- * @returns {Object|Array|Date|string|number} Deserialized thingy.
+ * @returns {Object|Array|string|number} Deserialized thingy.
*/
function fromJson(json) {
return isString(json)
@@ -815,7 +1075,9 @@ function fromJson(json) {
function toBoolean(value) {
- if (value && value.length !== 0) {
+ if (typeof value === 'function') {
+ value = true;
+ } else if (value && value.length !== 0) {
var v = lowercase("" + value);
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]');
} else {
@@ -832,7 +1094,7 @@ function startingTag(element) {
try {
// turns out IE does not let you set .html() on elements which
// are not allowed to have children. So we just ignore it.
- element.html('');
+ element.empty();
} catch(e) {}
// As Per DOM Standards
var TEXT_NODE = 3;
@@ -870,7 +1132,7 @@ function tryDecodeURIComponent(value) {
/**
* Parses an escaped url query string into key-value pairs.
- * @returns Object.<(string|boolean)>
+ * @returns {Object.<string,boolean|Array>}
*/
function parseKeyValue(/**string*/keyValue) {
var obj = {}, key_value, key;
@@ -879,7 +1141,14 @@ function parseKeyValue(/**string*/keyValue) {
key_value = keyValue.split('=');
key = tryDecodeURIComponent(key_value[0]);
if ( isDefined(key) ) {
- obj[key] = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
+ var val = isDefined(key_value[1]) ? tryDecodeURIComponent(key_value[1]) : true;
+ if (!obj[key]) {
+ obj[key] = val;
+ } else if(isArray(obj[key])) {
+ obj[key].push(val);
+ } else {
+ obj[key] = [obj[key],val];
+ }
}
}
});
@@ -889,14 +1158,22 @@ function parseKeyValue(/**string*/keyValue) {
function toKeyValue(obj) {
var parts = [];
forEach(obj, function(value, key) {
- parts.push(encodeUriQuery(key, true) + (value === true ? '' : '=' + encodeUriQuery(value, true)));
+ if (isArray(value)) {
+ forEach(value, function(arrayValue) {
+ parts.push(encodeUriQuery(key, true) +
+ (arrayValue === true ? '' : '=' + encodeUriQuery(arrayValue, true)));
+ });
+ } else {
+ parts.push(encodeUriQuery(key, true) +
+ (value === true ? '' : '=' + encodeUriQuery(value, true)));
+ }
});
return parts.length ? parts.join('&') : '';
}
/**
- * We need our custom method because encodeURIComponent is too agressive and doesn't follow
+ * We need our custom method because encodeURIComponent is too aggressive and doesn't follow
* http://www.ietf.org/rfc/rfc3986.txt with regards to the character set (pchar) allowed in path
* segments:
* segment = *pchar
@@ -916,7 +1193,7 @@ function encodeUriSegment(val) {
/**
* This method is intended for encoding *key* or *value* parts of query component. We need a custom
- * method becuase encodeURIComponent is too agressive and encodes stuff that doesn't have to be
+ * method because encodeURIComponent is too aggressive and encodes stuff that doesn't have to be
* encoded per http://tools.ietf.org/html/rfc3986:
* query = *( pchar / "/" / "?" )
* pchar = unreserved / pct-encoded / sub-delims / ":" / "@"
@@ -937,7 +1214,8 @@ function encodeUriQuery(val, pctEncodeSpaces) {
/**
* @ngdoc directive
- * @name ng.directive:ngApp
+ * @name ngApp
+ * @module ng
*
* @element ANY
* @param {angular.Module} ngApp an optional application
@@ -945,26 +1223,39 @@ function encodeUriQuery(val, pctEncodeSpaces) {
*
* @description
*
- * Use this directive to auto-bootstrap an application. Only
- * one ngApp directive can be used per HTML document. The directive
- * designates the root of the application and is typically placed
- * at the root of the page.
- *
- * The first ngApp found in the document will be auto-bootstrapped. To use multiple applications in an
- * HTML document you must manually bootstrap them using {@link angular.bootstrap}.
- * Applications cannot be nested.
- *
- * In the example below if the `ngApp` directive would not be placed
- * on the `html` element then the document would not be compiled
- * and the `{{ 1+2 }}` would not be resolved to `3`.
- *
- * `ngApp` is the easiest way to bootstrap an application.
- *
- <doc:example>
- <doc:source>
- I can add: 1 + 2 = {{ 1+2 }}
- </doc:source>
- </doc:example>
+ * Use this directive to **auto-bootstrap** an AngularJS application. The `ngApp` directive
+ * designates the **root element** of the application and is typically placed near the root element
+ * of the page - e.g. on the `<body>` or `<html>` tags.
+ *
+ * Only one AngularJS application can be auto-bootstrapped per HTML document. The first `ngApp`
+ * found in the document will be used to define the root element to auto-bootstrap as an
+ * application. To run multiple applications in an HTML document you must manually bootstrap them using
+ * {@link angular.bootstrap} instead. AngularJS applications cannot be nested within each other.
+ *
+ * You can specify an **AngularJS module** to be used as the root module for the application. This
+ * module will be loaded into the {@link auto.$injector} when the application is bootstrapped and
+ * should contain the application code needed or have dependencies on other modules that will
+ * contain the code. See {@link angular.module} for more information.
+ *
+ * In the example below if the `ngApp` directive were not placed on the `html` element then the
+ * document would not be compiled, the `AppController` would not be instantiated and the `{{ a+b }}`
+ * would not be resolved to `3`.
+ *
+ * `ngApp` is the easiest, and most common, way to bootstrap an application.
+ *
+ <example module="ngAppDemo">
+ <file name="index.html">
+ <div ng-controller="ngAppDemoController">
+ I can add: {{a}} + {{b}} = {{ a+b }}
+ </div>
+ </file>
+ <file name="script.js">
+ angular.module('ngAppDemo', []).controller('ngAppDemoController', function($scope) {
+ $scope.a = 1;
+ $scope.b = 2;
+ });
+ </file>
+ </example>
*
*/
function angularInit(element, bootstrap) {
@@ -1014,29 +1305,39 @@ function angularInit(element, bootstrap) {
/**
* @ngdoc function
* @name angular.bootstrap
+ * @module ng
* @description
* Use this function to manually start up angular application.
*
* See: {@l